java 实现生产者-消费者模式
生产和消费者模式有很多种,现在介绍几种常见的方式
- wait/notify实现生产和消费者模式
1、使用wait/notify实现生产和消费者模式:
public class Depot {
// 实际容量
private volatile int capacity = 0 ;
// 最大容量
private static final int MAX_CAPACITY = 100 ;
// 锁
private final Object lock = new Object() ;
public Depot(){
}
/**
* 生产
* @param: num
* @return:
*/
public void producer(int num) {
if(num<0){
System.out.println("生产数量不可为负数");
throw new IllegalArgumentException("生产数量不可为负数") ;
}
synchronized (lock){
// 生产
int left = 0;
try {
left = doProducer(num);
// 要求生产数量未达标,让出执行权
while (left > 0){
Thread.yield();
left = doProducer(left);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify();
}
}
/**
* 实际生产逻辑
* @param: num
* @return: 返回未生产数量
*/
private int doProducer(int num) throws InterruptedException {
// 实际增加数量
int grow = num ;
// 未生产数量
int left = 0 ;
// 等待仓库被消费
while (capacity>=MAX_CAPACITY){
lock.wait();
}
// 计算实际新增数量
if( (num+capacity) > MAX_CAPACITY ){
grow = MAX_CAPACITY - capacity ;
left = num - grow ;
}
capacity += grow ;
// 仓库已经生产,通知消费者消费
lock.notify();
System.out.println(Thread.currentThread().getName() + " Plan Producer = " + num + " Actually = " + grow + " left = " + left + " capacity = " + capacity);
return left ;
}
/**
* 消费
* @param: num
* @return:
*/
public void consumer(int num) {
if(num<0){
System.out.println("消费数量不可为负数");
throw new IllegalArgumentException("消费数量不可为负数") ;
}
synchronized (lock){
// 消费仓库
int left = 0;
try {
left = doConsumer(num);
// 要求消费数量未达标,让出执行权
while (left > 0){
Thread.yield();
left = doConsumer(left);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
// 仓库已经被消费,通知生产者生产
lock.notify();
}
}
/**
* 实际消费逻辑
* @param: num
* @return: 剩余未消费数量
*/
private int doConsumer(int num) throws InterruptedException {
// 实际消费数量
int decrease = num ;
// 剩余未消费
int left = 0 ;
// 等待仓库生产
while (capacity <= 0){
lock.wait();
}
// 计算实际消费数量
if(decrease > capacity){
decrease = capacity ;
left = decrease - capacity ;
}
capacity -= decrease ;
System.out.println(Thread.currentThread().getName() + " Plan Consumer = "+ num + " Actually = " + decrease + " left = " + left + " capacity = " + capacity );
return left ;
}
}
测试案例:
public class ProducerAndConsumer {
public static void main(String[] args) throws InterruptedException {
Depot depot = new Depot() ;
for(int x=0 ; x<4; x++){
new Thread(new Runnable() {
@Override public void run() {
depot.producer(40);
}
}).start();
}
Thread.sleep(2000L);
for(int x=0 ; x<3; x++){
new Thread(new Runnable() {
@Override public void run() {
depot.consumer(40);
}
}).start();
}
Thread.sleep(2000L);
}
}
运行结果:
Thread-0 Plan Producer = 40 Actually = 40 left = 0 capacity = 40
Thread-1 Plan Producer = 40 Actually = 40 left = 0 capacity = 80
Thread-2 Plan Producer = 40 Actually = 20 left = 20 capacity = 100
Thread-4 Plan Consumer = 40 Actually = 40 left = 0 capacity = 60
Thread-2 Plan Producer = 20 Actually = 20 left = 0 capacity = 80
Thread-3 Plan Producer = 40 Actually = 20 left = 20 capacity = 100
Thread-6 Plan Consumer = 40 Actually = 40 left = 0 capacity = 60
Thread-5 Plan Consumer = 40 Actually = 40 left = 0 capacity = 20
Thread-3 Plan Producer = 20 Actually = 20 left = 0 capacity = 40
其他待续.........
java 实现生产者-消费者模式的更多相关文章
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- java多线程 生产者消费者模式
package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...
- 关于java中生产者消费者模式的理解
在说生产者消费者模式之前,我觉得有必要理解一下 Obj.wait(),与Obj.notify()方法.wait()方法是指在持有对象锁的线程调用此方法时,会释放对象锁,同时休眠本线程.notify() ...
- java实现生产者消费者模式
生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将 ...
- java——利用生产者消费者模式思想实现简易版handler机制
参考教程:http://www.sohu.com/a/237792762_659256 首先说一下这里面涉及到的线程: 1.mainLooper: 这个线程可以理解为消费者线程,里面运行了一个死循环, ...
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...
- Java 生产者消费者模式详细分析
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- java ReentrantLock结合条件队列 实现生产者-消费者模式 以及ReentratLock和Synchronized对比
package reentrantlock; import java.util.ArrayList; public class ProviderAndConsumerTest { static Pro ...
- Java 学习笔记 使用并发包ReentrantLock简化生产者消费者模式代码
说明 ReentrantLock是java官方的一个线程锁类,ReentarntLock实现了Lock的接口 我们只需要使用这个,就可以不用使用synchronized同步关键字以及对应的notify ...
随机推荐
- 【官方文档】Nginx模块Nginx-Rtmp-Module学习笔记(一) RTMP 命令详解
源码地址:https://github.com/Tinywan/PHP_Experience 说明: rtmp的延迟主要取决于播放器设置,但流式传输软件,流的比特率和网络速度(以及响应时间“ping” ...
- 一些js的小技巧
这里收集了一些编码上的小技巧,大家可以学习学习. 1.浮点转整型 使用|0快速转换 var a=(12.002)|0;//12 使用~~快速转换 ~取反运算符,2=0010,~2=1101,因为第一位 ...
- RabbitMQ集群使用Haproxy负载均衡
(1).下载 http://www.haproxy.org/#down (2).解压 tar -zxvf haproxy-1.5.18.tar.gz (3).安装 1).编译 make TARGET= ...
- python3之模块psutil系统性能信息
psutil是个跨平台库,能够轻松实现获取系统运行的进程和系统利用率,包括CPU.内存.磁盘.网络等信息. 它主要应用于信息监控,分析和限制系统资源及进程的管理.它实现了同等命令命令行工具提供的功能, ...
- MYSQL 的 MASTER到MASTER的主主循环同步
MYSQL 的 MASTER到MASTER的主主循环同步 刚刚抽空做了一下MYSQL的主主同步.把步骤写下来,至于会出现的什么问题,以后随时更新.这里我同步的数据库是TEST1.环境描述. 主 ...
- bulk_write&Replace_one
ns=[]ns.append(ReplaceOne({'ip': ok['ip']}, ok, upsert=True))#更新插入 if len(ns) > 0: res = coll.bul ...
- Project Euler Problem3
Largest prime factor Problem 3 The prime factors of 13195 are 5, 7, 13 and 29. What is the largest p ...
- wpf 查找children的方法
var newValue = (bool)args.NewValue; HZWaitLoadingEx source = (HZWaitLoadingEx)sender; ControlTemplat ...
- 使用Windows 2008R2中的NFS替代Samba协议,解决Windows 与Linux共享文件的问题
一.在Windows服务器上进行安装NFS服务 首先,打开服务管理器,选择添加角色: 选中文件服务,下一步: 出现一个提示,不管它,继续下一步: 在接下来的页面中选中“网络文件 ...
- #JS attr和prop的区别
HTML元素固有属性:使用prop方法 HTML元素自定义属性:使用attr方法