互斥锁
在Object类中的notify方法只能是随机的唤醒单个线程,不能唤醒指定线程,为了弥补这个缺陷,在jdk5.0的版本中新增了ReenTrantLock类和Condition接口来替换synchronized关键字和wait、notify方法。
ReenTrantLock类和Condition接口都在java.util.concurrent.locks包下。
可以使用ReentrantLock类中的lock方法和unlock方法进行上锁和解锁,用来替代synchronized关键字。
Condition接口中的await方法和signal方法用来让线程等待和唤醒指定线程。用来替代wait方法和notify方法。
将上一节中三个线程之间的通信代码使用ReenTrantLock类和Condition接口重新实现
package com.sutaoyu.volatlt; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Print2 { //互斥锁 private ReentrantLock r= new ReentrantLock(); //监听器 private Condition c1 = r.newCondition(); private Condition c2 = r.newCondition(); private Condition c3 = r.newCondition(); private int flag = 1; public void print1() { r.lock(); while(flag != 1) { try { c1.wait(); }catch(InterruptedException e) { e.printStackTrace(); } } System.out.println("monkey"); flag = 2; //随机唤醒c2线程 c2.signal(); //在执行结束后释放锁 r.unlock(); } public void print2() { r.lock(); while(flag != 2) { try { c2.await(); }catch(InterruptedException e) { e.printStackTrace(); } } System.out.println("1024"); flag = 3; c3.signal(); r.unlock(); } public void print3() { r.lock(); while(flag != 3) { try { c3.await(); }catch(InterruptedException e) { e.printStackTrace(); } } System.out.println("888"); c1.signal(); r.unlock(); } }
package com.sutaoyu.volatlt; public class LockTest01 { public static void main(String[] args) { Print2 p = new Print2(); Thread t1 = new Thread(){ public void run(){ while(true){ p.print1(); } } }; Thread t2 = new Thread(){ public void run(){ while(true){ p.print2(); } } }; Thread t3 = new Thread(){ public void run(){ while(true){ p.print3(); } } }; t1.start(); t2.start(); t3.start(); } }