JDK1.5中引入了Java.util.concurrent.locks.Condition接口,用来替代wait/notify。wait/notify大家应该很了解,主要用来解决多线程的协调问题(等待/通知),但是其存在如下几个问题:
JUC中的Condition中await()、signal()、signalAll()分别对应Object中的wait()、notify()、notifyAll()方法。但是Condition更加灵活,并且解决了上述两个问题。
Condition的使用public class ConditionTest { public static void main(String[] args) { //JUC提供的工具锁 lock lock = new ReentrantLock(); //创建conditionA Condition conditionA = lock.newcondition(); //创建conditionB Condition conditionB = Lock.newCondition(); //WaitThreadA类的线程通过conditionA来实现等待 new WaitThreadA(lock, conditionA).start(); new WaitThreadA(lock, conditionA).start(); //WaitThreadB的线程通过conditionB来实现等待 new WaitThreadB(lock, conditionB).start(); //NotifyThreadA new NotifyThreadA(lock, conditionA).start(); } static class WaitThreadA extends Thread{ private Lock lock; private Condition condition; public WaitThreadA(Lock lock, Condition condition){ this.lock = lock; this.condition = condition; } @Override public void run() { lock.lock(); try { System.out.println("WaitA begin"); condition.await(); System.out.println("WaitA end"); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } } static class NotifyThreadA extends Thread{ private Lock lock; private Condition condition; public NotifyThreadA(Lock lock, Condition condition){ this.lock = lock; this.condition = condition; } @Override public void run() { lock.lock(); try { System.out.println("NotifyA begin"); condition.signalAll(); System.out.println("NotifyA end"); }finally { lock.unlock(); } } } static class WaitThreadB extends Thread{ private Lock lock; private Condition condition; public WaitThreadB(Lock lock, Condition condition){ this.lock = lock; this.condition = condition; } @Override public void run() { lock.lock(); try { System.out.println("WaitB begin"); condition.await(); System.out.println("WaitB end"); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } }}
运行结果
如代码所示,Condition实例通过Lock.newCondition()方法创建。Object.wait()/notify()要求其执行线程必须持有这些方法所属对象的内部锁,Condition也类似,其需要执行线程持有创建该Condition实例的显示锁(lock)。不同的是lock可以创建多个Condition,用来实现不同类型/条件的线程的等待/通知。如示例代码,NotifyThreadA类型线程通过conditionA实例仅仅用来通知WaitThreadA类型线程。如果使用Object.wait()/notify()只能通知所有持有该对象内部锁且处于wait状态的线程,无法按分类/条件唤醒。
Condition作用第一节已经说明了,Condition解决wait/notify存在的两个问题,在这一节我们总结一下Condition是如何解决这两个问题的。
总结:目前实际应用中推荐使用Condition来代替wait/notify。
参考《Java多线程实战指南(核心篇)》第五章——线程间协作
END
笔者是一位热爱互联网、热爱互联网技术、热于分享的年轻人,如果您跟我一样,我愿意成为您的朋友,分享每一个有价值的知识给您。喜欢作者的同学,点赞 转发 关注哦!