Java基础笔记-第十记
来源:互联网 发布:知乎top50 编辑:程序博客网 时间:2024/06/06 15:40
Java 线程三
在前一章的练习中,我们使用了 while 来实现每个线程被唤醒时都判断标记,以及使用 notyfyAll() 方法来唤醒所有线程,但这样做会发现,不应该被唤醒的线程也将被唤醒,这样做并不是最好的做法,下面介绍JDK1.5以后的新功能。
使用Lock和Condition 接口
Lock 接口通过 创建ReentrantLock 类来获取对象
Condition 接口通过 Lock的newCondition方法来获取对象
Lock 接口的 lock() 方法用来获取锁, 类似 synchronized
Lock 接口的 unLock() 方法释放锁, 必须要做的动作,建议放在 finally 块中
Condition 接口的await() 方法,用来设置当前线程等待
Condition 接口的signal()方法,用来唤醒其它线程
解决不应该被唤醒的线程也被唤醒的主要动作,是创建两个Condition对象,谁等待,谁唤醒则调用相应的方法,关键代码如下:
<span style="white-space:pre"></span>private Condition con_pro = lock.newCondition(); //生产者线程private Condition con_cus = lock.newCondition(); //消费者线程
当消费者消费完成后执行 con_cus.await(); 让消费方线程等待,并唤醒生产方线程 con_pro.signal();
完整代码如下:
import java.util.concurrent.locks.*;class Resource //资源类{private String name; private int count;public boolean flag;private Lock lock = new ReentrantLock();private Condition con_pro = lock.newCondition(); //生产者线程private Condition con_cus = lock.newCondition(); //消费者线程public synchronized void set(String name) {lock.lock();try{while(flag) { //每次唤醒时都会进行判断标记try {con_pro.await(); //让生产方线程等等} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}}this.name = name+"..."+count++;System.out.println(Thread.currentThread().getName()+ "生产者:" + this.name);flag = true;con_cus.signal(); //唤醒消费方线程}finally{lock.unlock();}}public void out(){lock.lock();try{while(!flag) { //每次唤醒时都会进行判断标记try {con_cus.await(); //消费方线程等待} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+".....消费者:" + this.name );flag = false;con_pro.signal();//唤醒生产方线程}finally{lock.unlock();}}}class Producer implements Runnable{private Resource res;public Producer(Resource res) {this.res = res;}@Overridepublic void run() {while(true){res.set("张三");}}}class Consumer implements Runnable{private Resource res;public Consumer(Resource res) {this.res = res;}@Overridepublic void run() {while(true){res.out();}}}public class Demo3 {public static void main(String[] args) {Resource res = new Resource();Producer pro = new Producer(res);Consumer con = new Consumer(res);Thread t1 = new Thread(pro);Thread t2 = new Thread(pro);Thread t3 = new Thread(con);Thread t4 = new Thread(con);t1.start();t2.start();t3.start();t4.start();}}
0 0
- Java基础笔记-第十记
- 【屌丝学习笔记】第十天 JAVA基础
- 【屌丝学习笔记】第十一天 JAVA基础
- 【屌丝学习笔记】第十三天 JAVA基础
- Java SE 学习笔记 第十记
- Java基础---第十一天 多线程
- Java基础第十九天--GUI
- java基础第十天 接口
- java基础第十一天 异常
- java基础第十五天 集合
- java基础第十八天 多线程
- Java基础部分第十三节
- Java基础部分第十五节
- Java基础部分第十八节
- java学习笔记--第十天
- 第十一次java课后笔记
- 第十二次java课后笔记
- java第十三次课后笔记
- web架构资料汇总
- USACO Betsy's Tour 解题报告
- android之底部导航
- CentOS系统下Apache负载均衡、Tomcat集群以及项目热部署配置
- 第10周项目2
- Java基础笔记-第十记
- SDWebImage加载图片原理
- 详解js中typeof、instanceof与constructor
- 安卓得到屏幕分辨率的四种方法
- 1103pickview
- LeetCodeOJ. Valid Palindrome
- 线程间的通信------------等待唤醒机制
- 第[4天] 函数——函数的应用 (重点掌握)
- Ubuntu下安装pip