生产者与消费者以及ActiveMQ
生产者与消费者以及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的更多相关文章
- 【Active入门-2】ActiveMQ学习-生产者与消费者
1个生产者,1个消费者,使用Queue: 方式1: 生产者将消息发送到Queue中,退出: 然后运行消费者: . 可以看到,可以接收到消息. 方式2: 先运行消费者程序: 然后运行生产者: 消费者见下 ...
- 【原创】JMS生产者和消费者【PTP同步接收消息】
一般步骤: 请求一个JMS连接工i厂. 是用连接工厂创建连接. 启动JMS连接. 通过连接创建session. 获取一个目标. 创建一个生产者,或a.创建一个生产者,b.创建一条JMS消息并发送到目标 ...
- 0032ActiveMQ之java编码实现生产者和消费者操作队列queue
今天学习了入门级的用java编写生产者producer和消费者consumer操作activemq的queue队列,为了之后复习回顾,现做整理如下: maven工程的搭建此处不再讲解,在maven工程 ...
- 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数
1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...
- LMAX Disruptor—多生产者多消费者中,消息复制分发的高性能实现
解决的问题 当我们有多个消息的生产者线程,一个消费者线程时,他们之间如何进行高并发.线程安全的协调? 很简单,用一个队列. 当我们有多个消息的生产者线程,多个消费者线程,并且每一条消息需要被所有的消费 ...
- JAVA并发框架之Semaphore实现生产者与消费者模型
分类: Java技术 锁和信号量(Semaphore)是实现多线程同步的两种常用的手段.信号量需要初始化一个许可值,许可值可以大于0,也可以小于0,也可以等于0. 如果大于0,表示 ...
- java 22 - 19 多线程之生产者和消费者的代码优化
在之前,是把生产者录入数据和消费者获取数据的所有代码都分别写在各自的类中. 这样不大好 这次把生产者和消费者部分关键代码都写入资源类中: package zl_Thread; public class ...
- java 22 - 16 多线程之生产者和消费者的问题
生产者和消费者问题的描述图 通过上图,我们可以发现: 生产者和消费者使用的都是同一个资源(肉包子) 所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题) 例子:学生信息的录入和获 ...
- Java实现生产者和消费者
生产者和消费者问题是操作系统的经典问题,在实际工作中也常会用到,主要的难点在于协调生产者和消费者,因为生产者的个数和消费者的个数不确定,而生产者的生成速度与消费者的消费速度也不一样,同时还要实现生产者 ...
随机推荐
- HDOJ 3398
这个题坑了太久太久啊!!!!!贡献了得有30+WA才发现 原来是因为在乘法中有溢出导致一直TLE啊.... 但是到最后也不知道有个问题怎么解决的. 就是在getp()中的num值的诡异的改变! #in ...
- Codeforces Round #637 (Div. 2)
比赛链接:https://codeforces.com/contest/1341 A - Nastya and Rice 题意 有 n 堆米,每堆质量在 [a-b,a+b] 之间,这些米的总质量是否可 ...
- Chocolate Bunny CodeForces - 1407C 思维
题意: 交互题 题目输入一个n,你需要输出一个满足要求的[1,n]的排列. 你可以最多询问2*n次来确定你要输出的排列·中每一个位置的值 每一次询问格式为"? a b" 它会回复你 ...
- hdu 6806 Equal Sentences 找规律
题意: 给你一个有n个单词的单词串S,对这n个单词进行排列组合形成新的一个单词串T,如果在S中任意某个单词所在位置,和这个单词在T中所在位置之差的绝对值小于等于1,那么就说S和T串相等 让你求S一共有 ...
- Codeforces Round #651 (Div. 2) B. GCD Compression (构造)
题意:有一个长度为\(2n\)的数组,删去两个元素,用剩下的元素每两两相加构造一个新数组,使得新数组所有元素的\(gcd\ne 1\).输出相加时两个数在原数组的位置. 题解:我们按照新数组所有元素均 ...
- GYM101810 ACM International Collegiate Programming Contest, Amman Collegiate Programming Contest (2018) M. Greedy Pirate (LCA)
题意:有\(n\)个点,\(n-1\)条边,每条边正向和反向有两个权值,且每条边最多只能走两次,有\(m\)次询问,问你从\(u\)走到\(v\)的最大权值是多少. 题解:可以先在纸上画一画,不难发现 ...
- String常用方法介绍
转载 int length(); 语法:字符串变量名.length(); 返回值为 int 类型.得到一个字符串的字符个数(中.英.空格.转义字符皆为字符,计入长度). String a=" ...
- LINUX - 通信
为什么三次握手: 让服务端和客户端都知道,自己的收信能力和发信能力没有问题: 第一次:客户端发给服务端--服务端知道了,自己的收信能力和客户端的发信能力没有问题: 第二次:服务端回复客户端--客户端知 ...
- java笔试中创建String对象的思考
题目是这样的下面那些生成新的String对象() A . String s = new String(); B . String s = new String("A"); C. ...
- CodeForces 1047C Enlarge GCD(数论)题解
题意:n个数的gcd是k,要你删掉最少的数使得删完后的数组的gcd > k 思路:先求出k,然后每个数除以k.然后找出出现次数最多的质因数即可. 代码: #include<cmath> ...