生产者消费者模型——wait/notify/notifyAll使用
告警系统架构如下
1、 数据处理系统处理完原始数据并入库后,发送消息到kafka系统;
2、 告警生产者从kafka系统查询消息存入告警消息队列;
3、 告警消费者从告警消息队列查询消息进行处理。
这显然是生产者消费者模型,一个告警消息生产者,多个告警消息消费者。生产者生产消息过快会产生消息积压,生产者生产消息过慢不能充分利用硬件资源。所以必须要生产者和消费者协同处理,使得系统充分利用。具体做法是消息队列为空时,消费者通知生产者生产消息,生产者生产好消息后,通知消费者处理消息。Java中我们使用的对象锁以及wait/notify方法进行线程通信,原理如下:
生产者——循环(获取锁synchronized,释放锁wait(等待被唤醒),生产消息)
消费者——循环(获取锁,消息空则notify/消息不空则消费消息)
消息队列代码:
package com.coshaho.threadpool; import java.util.ArrayList;
import java.util.List; /**
* 消息队列
* @author coshaho
*/
public class MessageQueue
{
List<String> messageList = new ArrayList<String>(); public boolean isEmpty()
{
return messageList.isEmpty();
} /**
* 消费消息
* @return
*/
public String consumeMessage()
{
return messageList.remove(0);
} /**
* 生产消息
* @param msg
*/
public void produceMessage(String msg)
{
messageList.add(msg);
}
}
消费者代码:
package com.coshaho.threadpool; /**
* 消费者,消息队列为空则唤醒生产者
* @author h00219638
*
*/
public class Customer implements Runnable
{
String name;
MessageQueue msgQueue;
public Customer(String name, MessageQueue msgQueue)
{
this.name = name;
this.msgQueue = msgQueue;
} @Override
public void run()
{
while(true)
{
// 消费消息
synchronized(msgQueue)
{
// 如果消息队列为空,唤醒生产者生产消息
if(msgQueue.isEmpty())
{
msgQueue.notify();
}
// 消息队列不为空,则消费消息
else
{
String msg = msgQueue.consumeMessage();
System.out.println("Customer " + name + " consumed message: " + msg + ".");
}
}
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
生产者代码:
package com.coshaho.threadpool; /**
* 生产者,消息队列为空时,消费者会唤醒生产者生产消息
* @author coshaho
*/
public class Producer implements Runnable
{
String name;
MessageQueue msgQueue;
public Producer(String name, MessageQueue msgQueue)
{
this.name = name;
this.msgQueue = msgQueue;
} @Override
public void run()
{
int i = 0;
while(true)
{
synchronized(msgQueue)
{
try
{
// 释放msgQueue的锁,等待消费者唤醒
msgQueue.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
// 唤醒后生产消息
for(int j = 0; j < 5; j++)
{
msgQueue.produceMessage("message_" + i + "_" + j);
}
}
System.out.println("Producer " + name + " produced 5 messages.");
}
} }
消息处理进程代码:
package com.coshaho.threadpool; /**
* 消息处理中心
* @author coshaho
*/
public class MessageProcessCenter
{
public static void main(String[] args)
{
// 初始化消息队列
MessageQueue msgQueue = new MessageQueue();
// 运行1个生产者
new Thread(new Producer("Producer", msgQueue)).start(); // 运行3个消费者
new Thread(new Customer("Customer1", msgQueue)).start();
new Thread(new Customer("Customer2", msgQueue)).start();
new Thread(new Customer("Customer3", msgQueue)).start();
}
}
运行结果:
Producer Producer produced 5 messages.
Customer Customer2 consumed message: message_0_0.
Customer Customer3 consumed message: message_0_1.
Customer Customer2 consumed message: message_0_2.
Customer Customer1 consumed message: message_0_3.
Customer Customer3 consumed message: message_0_4.
Producer Producer produced 5 messages.
Customer Customer3 consumed message: message_0_0.
Customer Customer1 consumed message: message_0_1.
Customer Customer2 consumed message: message_0_2.
Customer Customer1 consumed message: message_0_3.
Customer Customer3 consumed message: message_0_4.
Producer Producer produced 5 messages.
Customer Customer3 consumed message: message_0_0.
Customer Customer1 consumed message: message_0_1.
Customer Customer2 consumed message: message_0_2.
Customer Customer3 consumed message: message_0_3.
Customer Customer1 consumed message: message_0_4.
生产者消费者模型——wait/notify/notifyAll使用的更多相关文章
- 如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...
- 多线程-4.wait() notify() notifyAll() 生产者消费者模型
1.wait()方法 该方法继承于Object类.在调用obj.wait()方法后,当前线程会失去obj的锁.待其他线程调用obj.notify()或notifyAll()方法后进入锁等待池,争抢到锁 ...
- java线程基础巩固---多线程下的生产者消费者模型,以及详细介绍notifyAll方法
在上一次[http://www.cnblogs.com/webor2006/p/8419565.html]中演示了多Product多Consumer假死的情况,这次解决假死的情况来实现一个真正的多线程 ...
- 多线程学习-基础(十二)生产者消费者模型:wait(),sleep(),notify()实现
一.多线程模型一:生产者消费者模型 (1)模型图:(从网上找的图,清晰明了) (2)生产者消费者模型原理说明: 这个模型核心是围绕着一个“仓库”的概念,生产者消费者都是围绕着:“仓库”来进行操作, ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- Java多线程14:生产者/消费者模型
什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...
- Java生产者消费者模型
在Java中线程同步的经典案例,不同线程对同一个对象同时进行多线程操作,为了保持线程安全,数据结果要是我们期望的结果. 生产者-消费者模型可以很好的解释这个现象:对于公共数据data,初始值为0,多个 ...
- Java实现多线程生产者消费者模型及优化方案
生产者-消费者模型是进程间通信的重要内容之一.其原理十分简单,但自己用语言实现往往会出现很多的问题,下面我们用一系列代码来展现在编码中容易出现的问题以及最优解决方案. /* 单生产者.单消费者生产烤鸭 ...
- 【1】【JUC】Condition和生产者消费者模型
本篇文章将介绍Condition的实现原理和基本使用方法,基本过程如下: 1.Condition提供了await()方法将当前线程阻塞,并提供signal()方法支持另外一个线程将已经阻塞的线程唤醒. ...
随机推荐
- 用ELK打造可视化集中式日志
原文链接:https://yq.aliyun.com/articles/57420 摘要: Elk是Elastic search, Logstash和Kibana三者的简称. Elastic sear ...
- iOS计算两个时间的时间差
+ (long)calculteHourL:(NSDate *)endDate startDate:(NSDate *)startDate { NSCalendar *cal = [NSCalenda ...
- Java 多线程 ---- 线程中this与 Thread.currentThread()线程的区别
总结起来一句话:在Thread中调用this其实就是调用Thread私有Runnable类型的target,target是Thread类的一个属性,而Thread.currentThread()是指新 ...
- ABP之框架体系
一 .框架体系的介绍 ABP框架采用的是DDD(领域驱动设计)的原则,可以很方便实现项目之间的松耦合,采用模块化的方式,方便对框架的扩展. 按照DDD的原则,首先将项目分为四层: 展现层:用来展现给用 ...
- 11.23CSS笔记
每一步的编写过程都在代码里面书写了,暂且记录下来 <!DOCTYPE html> <html lang="en"> <head> <met ...
- CodeForces - 156B Suspects 逻辑 线性 想法 题
题意:有1~N,n(1e5)个嫌疑人,有m个人说真话,每个人的陈述都形如X是凶手,或X不是凶手.现在给出n,m及n个陈述(以+x/-X表示)要求输出每个人说的话是true ,false or notd ...
- ResourceManager High Availability
Introduction This guide provides an overview of High Availability of YARN’s ResourceManager, and det ...
- iOS服务器证书不受信任的解决版本
参考文章链接: https://www.cnblogs.com/v-jing/p/6008964.html http://www.cocoachina.com/ios/20151021/13722.h ...
- ArcGIS API for javascript开发笔记(二)——解决ArcGIS Service中的服务在内网环境下无法进行javascript预览问题
感谢一路走来默默支持和陪伴的你~~~ ----------------------------拒绝转载-------------------------------- 1.问题说明 在使用ArcGIS ...
- oracle显示转换字段类型cast()函数
今天遇到一个查询类型转换的问题:表的字段是varchar2类型,然后查询到的结果要转换为number(20,2),刚开始的时候使用to_number()函数,发现不能满足需求.后来才知道,原来还有ca ...