深入生产者与消费者模式
来源:互联网 发布:采集助手数据库 编辑:程序博客网 时间:2024/05/16 23:48
前提
本示例是生产者向堆栈中 List 对象中放入数据,使消费者从 List 堆栈中取出数据。List 最大容量是 1
一生产一消费——操作栈
MyStack代码
import java.util.ArrayList;import java.util.List;public class MyStack { private List list = new ArrayList(); synchronized public void push(){ try { if(list.size() == 1){ this.wait(); } list.add("anyString = "+ Math.random()); this.notify(); System.out.println("push = "+ list.size()); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized public String pop(){ String returnValue = ""; try { if(list.size() == 0){ this.wait(); } returnValue = list.get(0)+""; list.remove(0); this.notify(); System.out.println("pop = "+ list.size()); } catch (InterruptedException e) { e.printStackTrace(); } return returnValue; }}
MainThread代码
public class mainThread { public static void main(String[] args) { MyStack myStack = new MyStack(); ThreadP pThread = new ThreadP(myStack); ThreadC cThread = new ThreadC(myStack); pThread.start(); cThread.start(); }}class ThreadP extends Thread { private MyStack myStack; public ThreadP(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.push(); } }}class ThreadC extends Thread { private MyStack myStack; public ThreadC(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.pop(); } }}
输出结果
程序运行结果是 size() 不会大于1,通过生产者/消费者模式,两个操作交替进行
一生产与多消费——操作栈:解决 wait 条件改变与假死
启动多个消费者,只需要在 mainThread 中启动多个消费者线程,MyStack 不用更改。代码如下:
public class mainThread { public static void main(String[] args) { MyStack myStack = new MyStack(); ThreadP pThread = new ThreadP(myStack); ThreadC cThread1 = new ThreadC(myStack); ThreadC cThread2 = new ThreadC(myStack); pThread.start(); cThread1.start(); cThread2.start(); }}class ThreadP extends Thread { private MyStack myStack; public ThreadP(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.push(); } }}class ThreadC extends Thread { private MyStack myStack; public ThreadC(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.pop(); } }}
运行结果如下所示:
此问题的出现就是因为 MyStack 类中使用了 if 语句作为条件判断。
因为条件发生改变的时候并没有得到及时的响应,所以多个呈 wait 状态的线程被召唤,继而执行 list.remove(0) 代码出现异常。解决策略就是讲 if 更换为 while 语句。
解决办法当然还是采用 notifyAll()。将 MyStack 中两处 notify 变更为 notifyAll() 后即可。
多生产与一消费)——操作栈
启动多个生产者,只需要在 mainThread 中启动多个生产者线程,MyStack 不用更改。代码如下:
public class mainThread { public static void main(String[] args) { MyStack myStack = new MyStack(); ThreadP pThread1 = new ThreadP(myStack); ThreadP pThread2 = new ThreadP(myStack); ThreadC cThread = new ThreadC(myStack); pThread1.start(); pThread2.start(); cThread.start(); }}class ThreadP extends Thread { private MyStack myStack; public ThreadP(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.push(); } }}class ThreadC extends Thread { private MyStack myStack; public ThreadC(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.pop(); } }}
采用上面 “一生产/多消费”模式依旧可以唱功运行。
多生产者与多消费者:操作栈
启动多个生产者和多个消费者,只需要在 mainThread 中启动多个生产者线程和多个消费者线程,MyStack 不用更改。代码如下:
public class mainThread { public static void main(String[] args) { MyStack myStack = new MyStack(); ThreadP pThread1 = new ThreadP(myStack); ThreadP pThread2 = new ThreadP(myStack); ThreadC cThread = new ThreadC(myStack); pThread1.start(); pThread2.start(); cThread.start(); }}class ThreadP extends Thread { private MyStack myStack; public ThreadP(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.push(); } }}class ThreadC extends Thread { private MyStack myStack; public ThreadC(MyStack myStack) { super(); this.myStack = myStack; } public void run(){ while(true){ myStack.pop(); } }}
0 0
- 深入生产者与消费者模式
- 消费者与生产者模式
- 消费者与生产者模式
- 消费者与生产者模式
- 生产者与消费者模式
- 生产者与消费者模式
- 生产者与消费者模式
- 生产者与消费者模式
- 生产者与消费者模式
- 生产者与消费者模式
- 消费者与生产者模式2
- Linux:生产者与消费者模式
- JAVA 生产者与消费者模式
- 生产者/消费者模式之深入理解
- 深入线程:生产者与消费者问题
- 设计模式之:生产者与消费者模式
- 同步线程--生产者与消费者模式
- 用ACE实现生产者与消费者模式
- Android的IPC机制Binder
- JAVA编写的一个简单的Socket实现的HTTP响应服务器
- 自动化构建:一致性关键之道
- Java三大框架SSH与MVC的设计模式
- HDU 5882 Balanced Game(其实间接考查了欧拉回路)——2016 ACM/ICPC Asia Regional Qingdao Online
- 深入生产者与消费者模式
- 开博
- li标签、div标签等高度不同,依次排列错乱
- meta标签
- LeetCode 389: Find the Difference 题解
- Android Binder基本概念流程学习
- Udemy上免费的angualr2视频教程分享
- strcpy和memcpy主要有以下3方面的区别
- 基础概念4