之前文章有写wait/notify/notifyAll
Condition作用相似,可能会多一些性能 比方:反对不响应中断、可指定工夫点完结期待、可多条件(new 多个Condition)
Condition的await 与wait相似 必须在获取锁的时候能力await
一、 应用
/** * @author 木子的昼夜 */public class ConditionTest { public static Lock lock = new ReentrantLock(); // public static Condition cd01 = lock.newCondition(); public static void main(String[] args) throws InterruptedException { ConditionTest test = new ConditionTest(); new Thread(test::say01).start(); Thread.sleep(5000); new Thread(test::say02).start(); } /** * 说:我饿了 */ public void say01(){ try{ lock.lock(); System.out.println("我饿了"); cd01.await(); System.out.println("吃饱了"); } catch (Exception e){ e.printStackTrace(); } finally { lock.unlock(); } } /** * 说:饭好了 */ public void say02(){ try{ lock.lock(); cd01.signal(); System.out.println("开饭了"); } catch (Exception e){ e.printStackTrace(); } finally { lock.unlock(); } }}输入后果:我饿了开饭了吃饱了
二、 不响应中断
看一下say01 say02 可中断 say03 不可中断
public class ConditionTest02 { public static Object obj = new Object(); public static Lock lock = new ReentrantLock(); public static Condition cd01 = lock.newCondition(); public static void main(String[] args) throws InterruptedException { ConditionTest02 test = new ConditionTest02(); Thread thread = new Thread(test::say01); Thread thread02 = new Thread(test::say02); Thread thread03 = new Thread(test::say03); thread.start(); thread02.start(); thread03.start(); // 饿他们5秒钟 Thread.sleep(5000); // 中断 thread.interrupt(); thread02.interrupt(); // say03会中断失败 thread03.interrupt(); } /** * 说:小强饿了 */ public void say01(){ try{ lock.lock(); System.out.println("小强饿了"); System.out.println("小强期待投食"); cd01.await(); System.out.println("小强吃饱了"); }catch (InterruptedException e){ System.out.println("小强进来觅食了"); }catch (Exception e){ e.printStackTrace(); } finally { lock.unlock(); } } /** * 说:小明饿了 */ public void say02(){ try{ synchronized (obj){ System.out.println("小明饿了"); System.out.println("小明期待投食"); obj.wait(); System.out.println("小明吃饱了"); } } catch (InterruptedException e){ System.out.println("小明进来觅食了"); } } /** * 说:小月鸟饿了 中断无用 */ public void say03(){ try{ lock.lock(); System.out.println("小月鸟饿了"); System.out.println("小月鸟期待投食"); cd01.awaitUninterruptibly(); System.out.println("小月鸟吃饱了"); }catch (Exception e){ System.out.println("小月鸟进来觅食了"); e.printStackTrace(); } finally { lock.unlock(); } } }输入后果:小明饿了小明期待投食小强饿了小强期待投食小月鸟饿了小月鸟期待投食小明进来觅食了小强进来觅食了
三、 超时进行wait
condition能够await一段时间 本人意识到 没人理他 而后就完结await了
Object的wait也能够指定超时工夫
public class ConditionTest03 { public static Lock lock = new ReentrantLock(); // public static Condition cd01 = lock.newCondition(); public static void main(String[] args) { ConditionTest03 test = new ConditionTest03(); new Thread(test::say01).start(); } /** * 说:我饿了 */ public void say01(){ try{ lock.lock(); System.out.println("我饿了"); System.out.println("期待投喂"); // // 这个须要的单位是毫奥妙 也就是秒*1000*1000000 也就是5000000000L毫奥妙 = 5秒 // 也能够这样获取 nanos就等于 也就是5000000000L long nanos = TimeUnit.SECONDS.toNanos(5); long res = cd01.awaitNanos(5000000000L); // 也能够这样 返回true false // boolean res = cd01.await(10,TimeUnit.SECONDS); // 超时 if (res <= 0){ System.out.println("没人投喂 我本人觅食去"); } else { System.out.println("有人投喂 我吃饱了"); } } catch (Exception e){ e.printStackTrace(); } finally { lock.unlock(); } }}
四、指定工夫
能够指定到指定某个工夫点 就完结wait
public class LockTest04 { // 新建锁 public static Lock lock = new ReentrantLock(false); public static Condition cd = lock.newCondition(); public static void main(String[] args) throws InterruptedException { new Thread(()->{ try { lock.lock(); long l = System.currentTimeMillis(); l = l +1000*10; Date date = new Date(l); boolean res = cd.awaitUntil(date); if(res) { System.out.println("被告诉"); } else { System.out.println("没人告诉 到时见我本人走了"); } } catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } }).start(); }}
五、 创立多个condition
这里举个例子:小强 和 小月月 两个人在玩儿玩具 小强玩会儿 不玩儿了给小月月 小月月不玩了再给小强
public class PlayTest { public static Lock lock = new ReentrantLock(); public static Condition cd01 = lock.newCondition(); public static void main(String[] args) { PlayTest test = new PlayTest(); new Thread(test::xiaoqiangPlay).start(); new Thread(test::xiaoxuexuePlay).start(); } // 小强玩儿 public void xiaoqiangPlay(){ try { while (true){ lock.lock(); System.out.println("小强玩儿"); Thread.sleep(5000); // 告诉他人玩儿 cd01.signal(); // 本人等着他人告诉 cd01.await(); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } // 下月月玩 public void xiaoxuexuePlay(){ try { while(true){ lock.lock(); System.out.println("小月月玩儿"); Thread.sleep(5000); // 告诉他人玩儿 cd01.signal(); // 本人等着他人告诉 cd01.await(); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } }}
能够应用两个condition
public class PlayTest02 { public static Lock lock = new ReentrantLock(); public static Condition cd01 = lock.newCondition(); public static Condition cd02 = lock.newCondition(); public static void main(String[] args) { PlayTest02 test = new PlayTest02(); new Thread(test::xiaoqiangPlay).start(); new Thread(test::xiaoxuexuePlay).start(); } // 小强玩儿 public void xiaoqiangPlay(){ try { while (true){ lock.lock(); System.out.println("小强玩儿"); Thread.sleep(5000); // 告诉他人玩儿 cd01.signal(); // 本人等着他人告诉 cd02.await(); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } // 下月月玩 public void xiaoxuexuePlay(){ try { while(true){ lock.lock(); System.out.println("小月月玩儿"); Thread.sleep(5000); // 告诉他人玩儿 cd02.signal(); // 本人等着他人告诉 cd01.await(); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } }}
两个condition互不烦扰,能够指定condition await / signal
condition的signalAll 与 notifyAll 相似 不再代码演示
六、总结
- 创立Condition (可创立多个 互不影响)
- 必须在lock获取锁之后能力应用
- await 反对不相应中断、超时(Object wait也反对)、指定工夫点完结
- signal只会唤醒一个线程 signalAll 会唤醒所有线程
有问题能够留言哦,可也以公众号留言(回复快):