Lock - condition

Condition

以前文章有寫wait/notify/notifyAllide

Condition做用相似,可能會多一些功能 好比:支持不響應中斷、可指定時間點結束等待、可多條件(new 多個Condition)線程

Condition的await 與wait相似 必須在獲取鎖的時候才能awaitit

1、 使用

/**
 * @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();}}}輸出結果:
我餓了
開飯了
吃飽了

2、 不響應中斷

看一下say01 say02 可中斷 say03 不可中斷io

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();}}
   }輸出結果:
小明餓了
小明等待投食
小強餓了
小強等待投食
小月鳥餓了
小月鳥等待投食
小明出去覓食了
小強出去覓食了

3、 超時中止wait

condition能夠await一段時間 本身意識到 沒人理他 而後就結束await了class

Object的wait也能夠指定超時時間thread

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就等於 也就是5000000000Llong 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();}}}

4、指定時間

能夠指定到指定某個時間點 就結束waittest

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();}}

5、 建立多個condition

這裏舉個例子:小強 和 小月月 兩我的在玩兒玩具 小強玩會兒 不玩兒了給小月月 小月月不玩了再給小強date

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();}}}

可使用兩個conditionim

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 相似 再也不代碼演示

6、總結

  1. 建立Condition (可建立多個 互不影響)
  2. 必須在lock獲取鎖以後才能使用
  3. await 支持不相應中斷、超時(Object wait也支持)、指定時間點結束
  4. signal只會喚醒一個線程 signalAll 會喚醒全部線程
相關文章
相關標籤/搜索