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_pro.await(); 让生产方线程等待,并唤醒消费方线程 con_cus.signal();

当消费者消费完成后执行  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