回覆列表
  • 1 # 南極影解

    開發中不免會遇到需要所有子執行緒執行完畢通知主執行緒處理某些邏輯的場景。或者是執行緒 A 在執行到某個條件通知執行緒 B 執行某個操作。此時就要用到通訊.執行緒也是這個邏輯.誰都有需要幫助的時間.

    執行緒通訊常用的方式有:

    wait/notify 等待Volatile 記憶體共享CountDownLatch 併發工具使用 ReentrantLock 結合 Condition基本LockSupport實現執行緒間的阻塞和喚醒方式一:使用 volatile 關鍵字

    基於 volatile 關鍵字來實現執行緒間相互通訊是使用共享記憶體的思想,大致意思就是多個執行緒同時監聽一個變數,當這個變數發生變化的時候 ,執行緒能夠感知並執行相應的業務。這也是最簡單的一種實現方式

    執行結果為:

    方式二:使用Object類的wait() 和 notify() 方法

    眾所周知,Object類提供了執行緒間通訊的方法:wait()、notify()、notifyaAl(),它們是多執行緒通訊的基礎,而這種實現方式的思想自然是執行緒間通訊。

    注意: wait和 notify必須配合synchronized使用,wait方法釋放鎖,notify方法不釋放鎖

    執行結果為

    由列印結果截圖可知,線上程A發出notify()喚醒通知之後,依然是走完了自己執行緒的業務之後,執行緒B才開始執行,這也正好說明了,notify()方法不釋放鎖,而wait()方法釋放鎖。

    方式三:使用JUC工具類 CountDownLatch

    jdk1.5之後在java.util.concurrent包下提供了很多併發程式設計相關的工具類,簡化了我們的併發程式設計程式碼的書寫,***CountDownLatch***基於AQS框架,相當於也是維護了一個執行緒間共享變數state

    執行結果為:

    方式四:使用 ReentrantLock 結合 Condition

    執行結果為:

    顯然這種方式使用起來並不是很好,程式碼編寫複雜,而且執行緒B在被A喚醒之後由於沒有獲取鎖還是不能立即執行,也就是說,A在喚醒操作之後,並不釋放鎖。這種方法跟 Object 的 wait() 和 notify() 一樣。

    方式五:基本LockSupport實現執行緒間的阻塞和喚醒

    LockSupport 是一種非常靈活的實現執行緒間阻塞和喚醒的工具,使用它不用關注是等待執行緒先進行還是喚醒執行緒先執行,但是得知道執行緒的名字。

    執行結果

  • 中秋節和大豐收的關聯?
  • 大年初一都要做些什麼才是有意義的呢?