生产者与消费者以及ActiveMQ

一、 多线程实现生产者与消费者

1.1 生产者与消费者头文件

#pragma once

#include <iostream>

#include <mutex>

#include <thread>

#include <condition_variable>

class ProAndConClass

{

public:

ProAndConClass();

~ProAndConClass();

void printThread();

void addThread(int num);

bool g_flag = false;

private:

std::condition_variable g_cond_add_enable; //计算条件变量

std::condition_variable g_cond_print_enable;//打印条件

std::mutex g_mutex;

int g_value = 0;

bool g_print_able = false; //是否可以打印

};

1.2 实现cpp文件

#include "ProduceAndConsume.h"

//若不在堆上创建类的实例。需要将如下变量定义在全局数据区,不能放在类的内部,类成员变量可能分配在堆或者栈上,而线程是独享栈区的

//std::condition_variable g_cond_add_enable; //计算条件变量

//std::condition_variable g_cond_print_enable;//打印条件

//std::mutex g_mutex;

//int g_value = 0;

//bool g_print_able = false; //是否可以打印

ProAndConClass::ProAndConClass()

{

}

ProAndConClass::~ProAndConClass()

{

}

void ProAndConClass::addThread(int numThread)

{

std::cout << "add thread begin" << std::endl;

while (g_value < numThread)

{

std::unique_lock<std::mutex>my_lock(g_mutex);

g_cond_add_enable.wait(my_lock,

[=] {

return !g_print_able;

});

g_value++;

g_print_able = true;

std::cout << "++add thread" << g_value << std::endl;

g_cond_print_enable.notify_one(); //增加打印

}

//g_flag = false;

std::cout << "add thread leave"<<std::endl;

}

void ProAndConClass::printThread()

{

std::cout << "print thread begin" << std::endl;

while (g_flag)

{

std::unique_lock<std::mutex> my_lock(g_mutex);

g_cond_print_enable.wait(my_lock,

[=] {

return g_print_able;

});

g_print_able = false;

std::cout << "-- print thread" << g_value << std::endl;

g_cond_add_enable.notify_one();//通知增加线程

}

std::cout << "print thread leave" << std::endl;

}

1.3 主函数main

void testProAndCon()

{

ProAndConClass *proandcon = new(std::nothrow)ProAndConClass();//分配在堆上

proandcon->g_flag = true;

/*ProAndConClass proandcon;//如此,需要把变量定义到全局数据段.因为这种形式对象构

//造在栈区,而线程独享栈区

proandcon.g_flag = true;*/

//线程的初始化三种方式:普通函数、类成员函数、函数对象

std::thread thread_add(&ProAndConClass::addThread, proandcon, 10); // 生产者

std::thread thread_print(&ProAndConClass::printThread, proandcon); //消费者

//getchar();

Sleep(1000);

if (thread_add.joinable())

{

std::cout << "join add thread" << std::endl;

thread_add.join();

}

if (thread_print.joinable())

{

std::cout << "join print thread" << std::endl;

thread_print.join();

}

return;

}

1.4 生产者消费者小结

    使用两个线程,一个生产一个消费。两个线程是独享栈区的,所以测试的变量要放在他们可以共同可以操作的到的地方。

二、基于生产者消费者的MQ

2.1 代码调用过程

//Mq也分为生产者和消费者两个类

class
HelloWorldProducer : public Runnable {

private:

Connection* connection;

Session* session;

Destination* destination;

MessageProducer* producer;

int numMessages;

bool useTopic;

bool sessionTransacted;

std::string brokerURI;

private:

HelloWorldProducer(const
HelloWorldProducer&);

HelloWorldProducer& operator=(const
HelloWorldProducer&);

public:

HelloWorldProducer(const std::string&
brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted =
false) :

connection(NULL),

session(NULL),

destination(NULL),

producer(NULL),

numMessages(numMessages),

useTopic(useTopic),

sessionTransacted(sessionTransacted),

brokerURI(brokerURI) {

}

virtual ~HelloWorldProducer(){

cleanup();

}

void close() {

this->cleanup();

}

virtual void run() {

try {

//1 Create a ConnectionFactory

auto_ptr<ConnectionFactory>
connectionFactory(

ConnectionFactory::createCMSConnectionFactory(brokerURI));

// 2Create a Connection

connection =
connectionFactory->createConnection();

connection->start();

// 3Create a Session

if (this->sessionTransacted) {

session =
connection->createSession(Session::SESSION_TRANSACTED);

} else {

session = connection->createSession(Session::AUTO_ACKNOWLEDGE);

}

// 4Create the destination (Topic or Queue)

if (useTopic) {

destination =
session->createTopic("TEST.FOO");

} else {

destination =
session->createQueue("TEST.FOO");

}

// 5Create a MessageProducer from the Session to the Topic
or Queue

producer =
session->createProducer(destination);

producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT);

//6 Create the Thread Id String

string threadIdStr =
Long::toString(Thread::currentThread()->getId());

//7 Create a messages

string text = (string) "Hello
world! from thread " + threadIdStr;

for (int ix = 0; ix <
numMessages; ++ix) {

std::auto_ptr<TextMessage>
message(session->createTextMessage(text));

message->setIntProperty("Integer", ix);

printf("Sent message #%d
from thread %s\n", ix + 1, threadIdStr.c_str());

producer->send(message.get());

}

} catch (CMSException& e) {

e.printStackTrace();

}

}

private:

void cleanup() {

if (connection != NULL) {

try {

connection->close();

} catch (cms::CMSException& ex)
{

ex.printStackTrace();

}

}

// Destroy resources.

try {

delete destination;

destination = NULL;

delete producer;

producer = NULL;

delete session;

session = NULL;

delete connection;

connection = NULL;

} catch (CMSException& e) {

e.printStackTrace();

}

}

};

//消费者类

class
HelloWorldConsumer : public ExceptionListener,

public
MessageListener,

public Runnable {

private:

CountDownLatch latch;

CountDownLatch doneLatch;

Connection* connection;

Session* session;

Destination* destination;

MessageConsumer* consumer;

long waitMillis;

bool useTopic;

bool sessionTransacted;

std::string brokerURI;

private:

HelloWorldConsumer(const
HelloWorldConsumer&);

HelloWorldConsumer& operator=(const
HelloWorldConsumer&);

public:

HelloWorldConsumer(const std::string&
brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted =
false, int waitMillis = 30000) :

latch(1),

doneLatch(numMessages),

connection(NULL),

session(NULL),

destination(NULL),

consumer(NULL),

waitMillis(waitMillis),

useTopic(useTopic),

sessionTransacted(sessionTransacted),

brokerURI(brokerURI) {

}

virtual ~HelloWorldConsumer() {

cleanup();

}

void close() {

this->cleanup();

}

void waitUntilReady() {

latch.await();

}

virtual void run() {

try {

//1 Create a ConnectionFactory

auto_ptr<ConnectionFactory>
connectionFactory(

ConnectionFactory::createCMSConnectionFactory(brokerURI));

// 2Create a Connection

connection =
connectionFactory->createConnection();

connection->start();

connection->setExceptionListener(this);

//3 Create a Session

if (this->sessionTransacted ==
true) {

session =
connection->createSession(Session::SESSION_TRANSACTED);

} else {

session =
connection->createSession(Session::AUTO_ACKNOWLEDGE);

}

//4 Create the destination (Topic or Queue)

if (useTopic) {

destination =
session->createTopic("TEST.FOO");

} else {

destination =
session->createQueue("TEST.FOO");

}

//5 Create a MessageConsumer from the Session to the Topic
or Queue

consumer =
session->createConsumer(destination);

consumer->setMessageListener(this);

std::cout.flush();

std::cerr.flush();

//6 Indicate we are ready for messages.

latch.countDown();

// 7Wait while asynchronous messages come in.

doneLatch.await(waitMillis);

} catch (CMSException& e) {

// Indicate we are ready for
messages.

latch.countDown();

e.printStackTrace();

}

}

//8 Called from the consumer since this class is a registered
MessageListener.

virtual void onMessage(const Message*
message) {

static int count = 0;

try {

count++;

const TextMessage* textMessage =
dynamic_cast<const TextMessage*> (message);

string text = "";

if (textMessage != NULL) {

text =
textMessage->getText();

} else {

text = "NOT A
TEXTMESSAGE!";

}

printf("Message #%d Received:
%s\n", count, text.c_str());

} catch (CMSException& e) {

e.printStackTrace();

}

// Commit all messages.

if (this->sessionTransacted) {

session->commit();

}

// No matter what, tag the count down
latch until done.

doneLatch.countDown();

}

// If something bad happens you see it here
as this class is also been

// registered as an ExceptionListener with
the connection.

virtual void onException(const
CMSException& ex AMQCPP_UNUSED) {

printf("CMS Exception
occurred.  Shutting down
client.\n");

ex.printStackTrace();

exit(1);

}

private:

void cleanup() {

if (connection != NULL) {

try {

connection->close();

} catch (cms::CMSException& ex)
{

ex.printStackTrace();

}

}

// Destroy resources.

try {

delete destination;

destination = NULL;

delete consumer;

consumer = NULL;

delete session;

session = NULL;

delete connection;

connection = NULL;

} catch (CMSException& e) {

e.printStackTrace();

}

}

};

//main

int main(int
argc AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) {

activemq::library::ActiveMQCPP::initializeLibrary();

{

std::cout <<
"=====================================================\n";

std::cout << "Starting the
example:" << std::endl;

std::cout << "-----------------------------------------------------\n";

std::string brokerURI =

"failover:(tcp://localhost:61616"

//        "?wireFormat=openwire"

//       
"&transport.useInactivityMonitor=false"

//       
"&connection.alwaysSyncSend=true"

//        "&connection.useAsyncSend=true"

//       
"?transport.commandTracingEnabled=true"

//       
"&transport.tcpTracingEnabled=true"

//       
"&wireFormat.tightEncodingEnabled=true"

")";

bool useTopics = true;

bool sessionTransacted = false;

int numMessages = 2000;

long long startTime =
System::currentTimeMillis();

HelloWorldProducer  producer(brokerURI, numMessages, useTopics);

HelloWorldConsumer consumer(brokerURI,
numMessages, useTopics, sessionTransacted);

// Start the consumer thread.

Thread consumerThread(&consumer);

consumerThread.start();

// Wait for the consumer to indicate that
its ready to go.

consumer.waitUntilReady();

// Start the producer thread.

Thread producerThread(&producer);

producerThread.start();

// Wait for the threads to complete.

producerThread.join();

consumerThread.join();

long long endTime =
System::currentTimeMillis();

double totalTime = (double)(endTime -
startTime) / 1000.0;

consumer.close();

producer.close();

std::cout << "Time to completion
= " << totalTime << " seconds." << std::endl;

std::cout <<
"-----------------------------------------------------\n";

std::cout << "Finished with the
example." << std::endl;

std::cout << "=====================================================\n";

}

activemq::library::ActiveMQCPP::shutdownLibrary();

}

// END SNIPPET:
demo

生产者与消费者以及ActiveMQ的更多相关文章

  1. 【Active入门-2】ActiveMQ学习-生产者与消费者

    1个生产者,1个消费者,使用Queue: 方式1: 生产者将消息发送到Queue中,退出: 然后运行消费者: . 可以看到,可以接收到消息. 方式2: 先运行消费者程序: 然后运行生产者: 消费者见下 ...

  2. 【原创】JMS生产者和消费者【PTP同步接收消息】

    一般步骤: 请求一个JMS连接工i厂. 是用连接工厂创建连接. 启动JMS连接. 通过连接创建session. 获取一个目标. 创建一个生产者,或a.创建一个生产者,b.创建一条JMS消息并发送到目标 ...

  3. 0032ActiveMQ之java编码实现生产者和消费者操作队列queue

    今天学习了入门级的用java编写生产者producer和消费者consumer操作activemq的queue队列,为了之后复习回顾,现做整理如下: maven工程的搭建此处不再讲解,在maven工程 ...

  4. 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数

    1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...

  5. LMAX Disruptor—多生产者多消费者中,消息复制分发的高性能实现

    解决的问题 当我们有多个消息的生产者线程,一个消费者线程时,他们之间如何进行高并发.线程安全的协调? 很简单,用一个队列. 当我们有多个消息的生产者线程,多个消费者线程,并且每一条消息需要被所有的消费 ...

  6. JAVA并发框架之Semaphore实现生产者与消费者模型

    分类: Java技术      锁和信号量(Semaphore)是实现多线程同步的两种常用的手段.信号量需要初始化一个许可值,许可值可以大于0,也可以小于0,也可以等于0.      如果大于0,表示 ...

  7. java 22 - 19 多线程之生产者和消费者的代码优化

    在之前,是把生产者录入数据和消费者获取数据的所有代码都分别写在各自的类中. 这样不大好 这次把生产者和消费者部分关键代码都写入资源类中: package zl_Thread; public class ...

  8. java 22 - 16 多线程之生产者和消费者的问题

    生产者和消费者问题的描述图 通过上图,我们可以发现: 生产者和消费者使用的都是同一个资源(肉包子) 所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题) 例子:学生信息的录入和获 ...

  9. Java实现生产者和消费者

    生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...

随机推荐

  1. P2617 Dynamic Rankings (动态开点权值线段树 + 树状数组)

    题意:带修求区间k小 题解:回忆在使用主席树求区间k小时 利用前缀和的思想 既然是前缀和 那么我们可以使用更擅长维护前缀和的树状数组 但是这里每一颗权值线段树就不是带版本的 而是维护数组里i号点的权值 ...

  2. 【noi 2.6_162】Post Office(DP)

    这题和"山区建小学"除了输入不同,其他都一样.(解析可见我的上一篇随笔) 但是,这次我对dis[][]加了一个优化,画一下图就可明白. 1 #include<cstdio&g ...

  3. Gym 2009-2010 ACM ICPC Southwestern European Regional Programming Contest (SWERC 2009) A. Trick or Treat (三分)

    题意:在二维坐标轴上给你一堆点,在x轴上找一个点,使得该点到其他点的最大距离最小. 题解:随便找几个点画个图,不难发现,答案具有凹凸性,有极小值,所以我们直接三分来找即可. 代码: int n; lo ...

  4. 错误: 未能完成程序集的安装(hr = 0x8007000b)。探测终止。

     解决方案:VS中"工具"->"选项"->"Web项目"->"对网站和项目使用IIS Express的64位版& ...

  5. 51nod1459 带权最短路

    1459 迷宫游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 你来到一个迷宫前.该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分 ...

  6. hihoCoder Challenge 3

    #1065 : 全图传送 时间限制:30000ms 单点时限:3000ms 内存限制:256MB 描述 先知法里奥是 Dota 系列中的一个英雄.机动性强,推塔能力一流,打钱速度快,传送技能使先知可以 ...

  7. macOS & pbcopy

    macOS & pbcopy copy from command line pbcopy $ whoami | pbcopy # xgqfrms-mbp $ echo "hello, ...

  8. MobX All In One

    MobX All In One Simple, scalable state management. https://mobx.js.org/README.html https://github.co ...

  9. Swift All in One

    Swift All in One Swift 5.3 https://github.com/apple/swift-evolution Xcode https://developer.apple.co ...

  10. npm & cli & node.js

    npm & cli & node.js https://www.npmjs.com/ https://www.npmjs.com/settings/xgqfrms/packages h ...