黑马程序员_多线程间的通信(生产者与消费者)
来源:互联网 发布:淘宝名词解释大全 编辑:程序博客网 时间:2024/04/30 09:17
为了进一步体现线程的安全问题以及线程的等待唤醒机制。来看一个例子:
class Resource{private String name;private int count = 1;private boolean flag = false;public void set(String name){if (flag)try{wait();}catch (Exception e){}this.name = name+"---"+count++;System.out.println(Thread.currentThread().getName()+" produces "+this.name);flag = true;this.notify();}public void out(){if (!flag)try{wait();}catch (Exception e){}System.out.println(Thread.currentThread().getName()+" consumes "+this.name);flag = false;this.notify();}}如果只是开启了两个线程,运行时会轮流“消费--生产”很和谐。但如果两者各开启两条线程,就会出现这样的情况。
t1取得资格、执行权->生产商品1、将flag之位true后t1进入阻塞状态、t2取得资格和执行权->进入阻塞状态,t3取得资格和执行权->消费商品1->唤醒第一个进入线程池的t1、t3而后阻塞、t1取得资格,若同样取得资格t4抢到执行权->t4阻塞->t1取得执行权->生产商品2->唤醒t2、t2取得执行权后不再判断flag真假直接生产t3。
于是将if判断改为while循环,这样的确弥补了错误。但会导致t2"醒来"->判断flag真假->t2进入阻塞状态。造成了所有线程全部等待。于是使用notifyAll();总是唤醒全部线程。又一次解决了问题。
JDK1.5提供了多线程升级解决方案,将同步synchronized替换成现实lock操作,要为特定 Lock 实例获得 Condition 实例,使用其 newCondition() 方法。
以便通过将这些对象与任意 Lock 实现组合使用。
改动后的代码:
import java.util.concurrent.locks.*;class Resource{ private String name; private int count = 1; private boolean flag = false; private Lock lock = new ReentrantLock(); //将多个condition对象绑定到同一个锁上 private Condition condition_pro = lock.newCondition(); private Condition condition_con = lock.newCondition(); public void set(String name)throws InterruptedException { lock.lock(); try { while(flag) condition_pro.await(); this.name = name +"---"+count++; System.out.println(Thread.currentThread().getName()+"...producer..."+this.name); flag = true; condition_con.signal(); //唤醒对方 } finally { lock.unlock(); } } public void out() throws InterruptedException { lock.lock(); try { while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+"...consumes..."+this.name); flag = false; condition_pro.signal(); } finally { lock.unlock(); } }}class Producer implements Runnable{ private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) { try { res.set("+商品+"); } catch (InterruptedException e) { } } }}class Consumer implements Runnable{ private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while (true) { try { res.out() } catch (InterruptedException e) { } } }}
0 0
- 黑马程序员_多线程间的通信(生产者与消费者)
- 黑马程序员-----多线程之间的通信(生产者消费者)
- 黑马程序员_多线程之生产者与消费者
- 黑马程序员------多线程(No.2)(死锁、线程间通信、生产者消费者问题)
- 黑马程序员-多线程(生产者与消费者问题)
- 35.黑马程序员-线程间通信(生产者消费者)
- 黑马程序员_多线程:生产者消费者练习实例及问题
- 多线程通信(生产者与消费者)
- 多线程通信(生产者与消费者)
- 多线程_生产者与消费者
- 黑马程序员_日记18_Java多线程(八)--生产者消费者问题JDK1.5特性
- 黑马程序员-多线程经典之消费者与生产者
- 黑马程序员_java多线程中的生产者与消费者
- 黑马程序员_2_多线程之生产者与消费者
- java多线程-线程间通信_生产者消费者
- 黑马程序员----多线程之生产者消费者问题
- 黑马程序员-java多线程生产者消费者问题
- 线程间的通信(生产者与消费者)
- 在Tomcat中部署默认项目
- uC/OS - II中的代码技巧
- 欢迎测试谈感受
- 《计算机网络 自顶向下方法》读书笔记(四)
- 计算机与信息工程系课程实验报告
- 黑马程序员_多线程间的通信(生产者与消费者)
- C++11 lambda 表达式
- 第三周项目五数组作数据成员(5)
- bzoj2127: happiness 最小割
- Hbase系统架构及数据结构
- cocos2d 模拟触摸
- T-SQL 游标
- linux命令后台运行
- iOS键盘高度及键盘响应事件