并發編程中的線程間通信
線程通信的目標是使線程間能夠互相發送信號。另一方面,線程通信使線程能夠等待其他線程的信號。
線程通信常用的方式有:
- 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 是一種非常靈活的實現線程間阻塞和喚醒的工具,使用它不用關注是等待線程先進行還是喚醒線程先運行,但是得知道線程的名字。

運行結果
