(7)Java多线程之消费者/生产者模式
来源:互联网 发布:mac版ps cs6破解补丁 编辑:程序博客网 时间:2024/05/18 11:15
- 引言
- 一生产一消费情况
- 1 生产者Producer
- 2 消费者Customer
- 3 main函数
- 4 运行结果
- 一生产多消费
- 1 生产者Producer代码不变
- 2 消费者Customer
- 3main方法
- 4 运行结果
- 5 修改代码的原因
- 多生产一消费
- 1 生产者代码修改两处
- 2 消费者代码和一生产一消费的消费者代码一样
- 3main函数代码
- 多生产多消费
- 1生产者代码和多生产一消费代码一样
- 2消费者代码和一生产多消费代码一样
- 3main代码
- 4 多生产多消费代码的缺陷
- 总结
1. 引言
在上一篇博客中,我们介绍了第四种线程之间的通信方式:等待通知机制。等待通知机制最典型的例子:消费者/生产者模式。在此篇博客中主要介绍等待通知机制中的:消费者/生产者模式,
什么是消费者/生产者模式?假设我们要生产一种产品,我们一类线程用于生产产品,另外一类线程用于消费产品。在这个Demo中需要三种类:
- 产品(这里我们用array数组代替)
- 生产者
- 消费者
在消费者/生产者模式中过程介绍
- 在生产者/消费者模式中,产品的数量为1 (注意产品的数量要么等于0,要么等于1)
- 对于生产者来说:如果产品的数量为0,那么生产者应该生产产品,并且生产者通知消费者,让消费者消费。如果产品数量等于1,那么生产者应该等待消费者消费,如果消费者不消费,生产者将一直等待下去
- 对于消费者来说:如果产品的数量等于0,那么消费者应该等待生产者生产,如果产品的数量等译1,那么消费者进行消费,消费完成后应该通知生产者生产商品
消费者/生产者模式一共分为以下几种情况:一生产一消费,一生产多消费,多生产一消费,多生产多消费
2. 一生产一消费情况
2.1 生产者(Producer
)
import java.util.List;//生产者public class Producer { // arr是我们的产品 private List arr; // 用于控制等待通知机制的对象锁 private Object lock; public Producer(List arr, Object lock) { this.arr = arr; this.lock = lock; } // 用户生产产品的方法 public void addProduct() throws Exception { synchronized (lock) { if (arr.size() > 0) { System.out.println("已经拥有了一个产品,陷入等待"); lock.wait(); } System.out.println("我要生产产品了"); arr.add("牛奶"); lock.notify(); } }}
2.2 消费者(Customer
)
import java.util.List;public class Customer { // arr是我们的产品 private List arr; // 用于控制等待通知机制的对象锁 private Object lock; public Customer(List arr, Object lock) { this.arr = arr; this.lock = lock; } // 用于消费的方法 public void csmProduct() throws Exception { synchronized (lock) { if (arr.size() == 0) { System.out.println("没有产品,等待中"); lock.wait(); } System.out.println("消费产品" + arr.get(0)); arr.remove(0); // 通知生产者生产 lock.notify(); } }}
2.3 main函数
import java.util.ArrayList;import java.util.List;public class app { public static void main(String[] args) { // 创建我们的产品 List arr = new ArrayList(); // 创建我们的锁 Object lock = new Object(); // 创建消费者 final Customer c = new Customer(arr, lock); // 创建生产者 final Producer p = new Producer(arr, lock); // 消费者线程 Runnable ct = new Runnable() { public void run() { try { while (true) { c.csmProduct(); } } catch (Exception e) { e.printStackTrace(); } } }; // 生产者线程 Runnable pt = new Runnable() { public void run() { try { while (true) { p.addProduct(); } } catch (Exception e) { e.printStackTrace(); } } }; // 创建一个生产者 new Thread(pt).start(); // 创建一个消费者 new Thread(ct).start(); }}
2.4 运行结果
- 从上面例子可以看出来,我们通过等待通知机制成功实现了一生产一消费的生产者消费模式
- 注意:线程ct和现成pt都需要获得
lock
对象锁 - 注意:一生产一消费代码是可以这样写的,在多生产多消费的代码中就要修改了。
3.一生产多消费
3.1 生产者(Producer
)(代码不变)
3.2 消费者(Customer
)
import java.util.List;public class Customer { // arr是我们的产品 private List arr; // 用于控制等待通知机制的对象锁 private Object lock; public Customer(List arr, Object lock) { this.arr = arr; this.lock = lock; } // 用于消费的方法 public void csmProduct() throws Exception { synchronized (lock) { while (arr.size() == 0) { System.out.println("没有产品,等待中"); lock.wait(); } System.out.println("消费产品" + arr.get(0)); arr.remove(0); // 通知生产者生产(注意这里代码修改了) lock.notifyAll(); } }}
- 注意代码修改的两个地方:
- 一个是判断产品的数量,由以前的
if
改为了while
- 一个是唤醒线程由:由
notify()
改为了notifyAll()
3.3main方法
//...上面代码和一生产一消费一样 // 创建一个生产者 new Thread(pt).start(); // 创建三个消费者 new Thread(ct).start(); new Thread(ct).start(); new Thread(ct).start();
3.4 运行结果
3.5 修改代码的原因
4 多生产一消费
4.1 生产者代码(修改两处)
import java.util.List;//生产者public class Producer { // arr是我们的产品 private List arr; // 用于控制等待通知机制的对象锁 private Object lock; public Producer(List arr, Object lock) { this.arr = arr; this.lock = lock; } // 用户生产产品的方法 public void addProduct() throws Exception { synchronized (lock) { //修改的第一处 while (arr.size() > 0) { System.out.println("已经拥有了一个产品,陷入等待"); lock.wait(); } System.out.println("我要生产产品了"); arr.add("牛奶"); //修改的第二处 lock.notifyAll(); } }}
- 原理和一生产多消费的原理一样,参考上面的原理图
4.2 消费者代码(和一生产一消费的消费者代码一样)
4.3main函数代码
//......上面的代码和一生产一消费的代码一样 // 创建三个生产者 new Thread(pt).start(); new Thread(pt).start(); new Thread(pt).start(); // 创建一个消费者 new Thread(ct).start();
5.多生产/多消费
5.1生产者代码(和多生产一消费代码一样)
5.2消费者代码(和一生产多消费代码一样)
5.3main代码
//.....上面代码和一生产一消费一样 // 创建三个生产者 new Thread(pt).start(); new Thread(pt).start(); new Thread(pt).start(); // 创建三个消费者 new Thread(ct).start(); new Thread(ct).start(); new Thread(ct).start();
5.4 多生产多消费代码的缺陷
6. 总结
在本篇博客中,主要利用等待通知机制实现了消费者生产者模式,其中包括有一生产一消费,多生产一消费,一消费多生产,多生产多消费等情况。注意:上面的例子,产品的数量最多是1。还有注意本篇博客,多生产多消费中代码的缺陷。
1 0
- (7)Java多线程之消费者/生产者模式
- java多线程之消费者生产者模式
- Java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- Java多线程之生产者消费者模式
- Java多线程之三生产者消费者模式
- Java多线程之生产者-消费者模式
- Java多线程之生产者-消费者模式
- java多线程之生产者消费者模式
- java多线程之消费者生产者模式(一)
- (10)Java多线程之再看生产者/消费者模式
- Java多线程生产者/消费者模式(一)
- Java多线程生产者/消费者模式(二)
- 多线程之生产者消费者模式
- RabbitMQ学习笔记二:rabbitmq发送接收消息Helloworld(Java版)
- mac Rstudio 环境下对象无法永久清除的解决办法
- Hadoop-YARN(资源管理系统)
- 1月16号页面布局练习
- webpack 入门必知必会
- (7)Java多线程之消费者/生产者模式
- 集合——Array和ArrayList的使用
- OpenLayers3的轨迹回放
- linux crontab
- 统计图控件ChartControl的横轴滚动条用法
- Java设计模式之策略模式
- Glide 一个专注于平滑滚动的图片加载和缓存库
- ORACLE expdp备份到windows网络共享文件目录(NFS)
- Android修改主题,去掉ActionBar、TitleBar