java多线程二
2015-06-16 15:35
609 查看
对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的。
前面叙述生产消费者模型,仓库中存在单一产品的问题,
* 多线程生产者消费者模型
* 主要讲解线程同步问题,类Object中的wait,notify和notifyAll方法以及Synchronized关键字的使用
*
* 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。对于此模型,应该明确一下几点:
* 1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
* 2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
* 3、当消费者发现仓储没产品可消费时候会通知生产者生产。
* 4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。
* 此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。
运行结果:
当custom4进行消费时,发现curnum=0,custom4进入线程池中等待,等待生产者进行生产,
当produce2和produce3生产出满足消费的数量时,custom4被唤醒并进行消费。
...................................
前面叙述生产消费者模型,仓库中存在单一产品的问题,
* 多线程生产者消费者模型
* 主要讲解线程同步问题,类Object中的wait,notify和notifyAll方法以及Synchronized关键字的使用
*
* 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。对于此模型,应该明确一下几点:
* 1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
* 2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
* 3、当消费者发现仓储没产品可消费时候会通知生产者生产。
* 4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。
* 此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是非常重要的。
public class Pc { public static void main(String[] args) { Godown godown = new Godown(50); new Thread(new Produce(10, godown), "produce1").start(); new Thread(new Consume(godown, 20), "custom1").start(); new Thread(new Consume(godown, 20), "custom2").start(); new Thread(new Consume(godown, 20), "custom3").start(); new Thread(new Consume(godown, 20), "custom4").start(); new Thread(new Produce(10, godown), "produce2").start(); new Thread(new Produce(10, godown), "produce3").start(); new Thread(new Produce(10, godown), "produce4").start(); new Thread(new Produce(10, godown), "produce5").start(); new Thread(new Produce(10, godown), "produce6").start(); } } class Consume implements Runnable{ private Godown godown; private int num ; public Consume(Godown godown , int num){ this.godown = godown; this.num=num; } @Override public void run() { godown.consume(num); } } class Produce implements Runnable{ private Godown godown ; private int num ; public Produce(int num , Godown godown){ this.godown = godown; this.num = num; } @Override public void run() { godown.produce(num); } } class Godown{ private static final int MAX_SIZE = 100; private int curnum ; public Godown() { } public Godown(int curnum){ this.curnum = curnum; } public synchronized void produce(int num){ while(curnum+num > MAX_SIZE){ try { System.out.println(Thread.currentThread().getName()+" 生产数量:"+num+"+库存:"+curnum+">最大容量,produce线程wait"); wait(); System.out.println(Thread.currentThread().getName()+" 生产线程被唤醒,继续运行。"); } catch (InterruptedException e) { e.printStackTrace(); } } curnum+=num; System.out.println(Thread.currentThread().getName()+"生产了:"+num+"个,目前产品数量:"+curnum); notifyAll(); } public synchronized void consume(int num){ while(num>curnum){ try { System.out.println(Thread.currentThread().getName()+" 消费数量:"+num+" +库存"+curnum+" 超出库存最大容量,custom等待"); wait(); System.out.println(Thread.currentThread().getName()+"消费线程被唤醒"); } catch (InterruptedException e) { e.printStackTrace(); } } curnum-=num; System.out.println(Thread.currentThread().getName()+"消费了:"+num+"个,目前产品数量为:"+curnum); notifyAll(); } }
运行结果:
produce1生产了:10个,目前产品数量:60 custom1消费了:20个,目前产品数量为:40 custom2消费了:20个,目前产品数量为:20 custom3消费了:20个,目前产品数量为:0 custom4 消费数量:20 +库存0 超出库存最大容量,custom等待 produce2生产了:10个,目前产品数量:10 custom4消费线程被唤醒 custom4 消费数量:20 +库存10 超出库存最大容量,custom等待 produce3生产了:10个,目前产品数量:20 custom4消费线程被唤醒 custom4消费了:20个,目前产品数量为:0 produce4生产了:10个,目前产品数量:10 produce5生产了:10个,目前产品数量:20 produce6生产了:10个,目前产品数量:30
</pre><pre name="code" class="java">运行流程
当custom4进行消费时,发现curnum=0,custom4进入线程池中等待,等待生产者进行生产,
当produce2和produce3生产出满足消费的数量时,custom4被唤醒并进行消费。
...................................
相关文章推荐
- Java设计模式--工厂模式
- 使用replaceAll()替换有"+"的字符串出现:java.util.regex.PatternSyntaxException
- (转)Spring读书笔记-----Spring的Bean之Bean的基本概念
- 在Eclipse中使用JUnit4进行单元测试(高级篇)
- Java面向对象 继承类的一些特殊写法
- spring security 11种过滤器介绍
- java中对list集合中的数据按照某一个属性进行分组
- Java JAX-WS和JAX-RS webservice的区别和特点
- 接口测试-自动化-Java实现-TestMain
- myeclipse2015-version-comparison.pdf
- java学习路线
- Java实现获取文件MD5
- Zookeeper 03 Java访问Zookeeper
- springmvc数据验证
- JAVA将反斜杠"\"转成正斜杠"/"
- Maven中maven-source-plugin,maven-javadoc-plugin插件的使用:
- eclipse 创建maven项目设置默认jdk版本
- 使用spring的 scheduled的注解进行定时任务
- 接口测试-自动化-Java-思路整理后
- (转)Spring读书笔记-----使用Spring容器(二)