[笔记][Java7并发编程实战手册]2.4在同步代码中使用条件-生产者与消费者
2015-08-08 17:40
597 查看
[笔记][Java7并发编程实战手册]系列目录
以上方法详细解说请查看: Java多线程系列–“基础篇”05之 线程等待与唤醒
说明:
上面示例大致逻辑:生产者不停的生产给仓库,仓库容量是10,达到最大容量则暂停生产;
消费者,不停的消费,仓库中有商品的时候才可以消费,否则等待;
说明
在并发编程中一个典型的问题是生产者–消费者问题。在程序中,有可能会需要用到两个线程通信的情况,比如生产者消费者中,获取一个共享数据,有就消费。没有就等待着生产者生产之后再继续消费。那么这个实现过程就可以使用wait();notify();notifyAll()来达到效果;以上方法详细解说请查看: Java多线程系列–“基础篇”05之 线程等待与唤醒
例子
/** * Created by zhuqiang on 2015/8/8 0008. */ public class Client { public static void main(String[] args) { Storage st = new Storage(); new Thread(new Producer(st), "小红").start(); new Thread(new Consumer(st), "小名").start(); } } /** * 仓库 */ class Storage { private int maxSize = 10; //仓库最大容量 private LinkedList<Date> st = new LinkedList<Date>(); //仓库存储 /** 生产 */ public synchronized void producer() { while (st.size() > maxSize) { try { System.out.println(Thread.currentThread().getName() + " : 仓库满了,生产着等待生产中"); this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } st.push(new Date()); System.out.println(Thread.currentThread().getName() + " : 生产了一个商品"); this.notifyAll(); //唤醒其他等待的线程 } /** 消费 */ public synchronized void consumer() { while (st.size() == 0) { // 要注意这里, 进来一次,就要循环的判断如果一直没有库存,则一直等待,因为notifyAll()是唤醒所在在此监视器锁上等待的线程,有可能抢到资源的还是当前线程 try { System.out.println(Thread.currentThread().getName() + " : 正在等待商品:当前商品数量:" + st.size()); this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " : 消费商品:" + st.pop()); this.notifyAll(); //唤醒其他等待线程(唤醒 生产者) } public int getMaxSize() { return maxSize; } public void setMaxSize(int maxSize) { this.maxSize = maxSize; } public LinkedList<Date> getSt() { return st; } public void setSt(LinkedList<Date> st) { this.st = st; } } /** 生产者 */ class Producer implements Runnable { private Storage st; public Producer(Storage st) { this.st = st; } @Override public void run() { /*for (int i = 1;i <=50;i++)*/ while (true) { st.producer(); } } } /** 消费者 */ class Consumer implements Runnable { private Storage st; public Consumer(Storage st) { this.st = st; } @Override public void run() { /*for (int i = 1;i <=50;i++)*/ //这里不能使用循环多少次来模拟,不然会出现(假死锁),假如生产者的循环次数先循环完,那么消费者的循环次数还没有循环完,而又没有商品了,那么消费者则一直等待。没有人唤醒 while (true) { st.consumer(); } } }
说明:
上面示例大致逻辑:生产者不停的生产给仓库,仓库容量是10,达到最大容量则暂停生产;
消费者,不停的消费,仓库中有商品的时候才可以消费,否则等待;
相关文章推荐
- Java生成和操作Excel文件
- 利用Java反射机制和泛型,全自动解析json
- java命令行运行main时jar及其配置
- Java串口通信 ----> 扫描标签获取数据存入数据库
- javaweb中利用filter进行修改字符集
- Spring AOP 实现原理
- java char 和 int 向上转型
- [Java]如何避免啰嗦的代码风格
- 在eclipse 中运行 需sudo root权限执行的程序
- java 集合框架 泛型--15
- java生成csv格式的文件
- spring中scope作用域(转)
- Java加密与解密的艺术-读书笔记1-2章
- Java反射机制之类类型
- JAVA学习笔记(五)
- java i++ 和 ++i 深度解析
- 学习笔记——ajax传值数组对象中遇到的问题
- 2014届华为校园招聘机试题(java实现)
- Java:谈谈protected访问权限
- 线程通信2