Java多執行緒通訊lock和wait
- 2020 年 1 月 21 日
- 筆記
在Java多執行緒中有一對配合使用過的兩個方法,來實現執行緒間通訊的功能–lock和wait, 由於這個需要獲得鎖,所以必須結合synchronized一起使用。首先我們先看一個例子:
public class LockWait { static volatile List<String> itemContainer = new ArrayList<>(); static Object obj = new Object(); public static void main(String[] args) { Thread th1 = new Thread(() -> { synchronized (obj) { for (int i = 0; i < 10; i++) { System.out.println("th1添加元素"); itemContainer.add(String.valueOf(i)); if (itemContainer.size() == 5) { System.out.println("th1執行緒發出通知"); obj.notify(); } } } }); Thread th2 = new Thread(() -> { synchronized (obj) { System.out.println("進入th2執行緒"); if (itemContainer.size() != 5) { try { System.out.println("th2執行緒開始等待"); obj.wait(); System.out.println("th2執行緒等待結束"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("th2執行緒結束"); } } }); th2.start(); th1.start(); } }
輸出結果如下:
進入th2執行緒 th2執行緒開始等待 th1添加元素 th1添加元素 th1添加元素 th1添加元素 th1添加元素 th1執行緒發出通知 th1添加元素 th1添加元素 th1添加元素 th1添加元素 th1添加元素 th2執行緒等待結束 th2執行緒結束
具體運行邏輯如下:

總結上面的運行結果,th2在wait的時候,th1可以持有鎖。說明wait是釋放鎖,而notify不釋放鎖。
這樣也就帶來了一個弊端,無法實時的得到結果,就是說當List達到我們想要的結果的時候,th1執行緒一直還在持有鎖,導致th2無法執行。
有沒有更好辦法呢?在Java中提供了一個CountDownLatch類:
public class CountDownLatchTest { public static void main(String[] args) { final List<String> itemContainer = new ArrayList<>(); final CountDownLatch countDownLanch = new CountDownLatch(1); Thread th1 = new Thread(() -> { for (int i = 0; i < 10; i++) { try { System.out.println("th1添加元素"); itemContainer.add(String.valueOf(i)); if (itemContainer.size() == 5) { System.out.println("th1執行緒發出通知"); countDownLanch.countDown(); } } catch (Exception e) { e.printStackTrace(); } } }); Thread th2 = new Thread(() -> { System.out.println("進入th2執行緒"); if (itemContainer.size() != 5) { try { System.out.println("th2執行緒開始等待"); countDownLanch.await(); System.out.println("th2執行緒等待結束"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("th2執行緒結束"); } }); th2.start(); th1.start(); } }
運行結果:
進入th2執行緒 th1添加元素 th2執行緒開始等待 th1添加元素 th1添加元素 th1添加元素 th1添加元素 th1執行緒發出通知 th1添加元素 th2執行緒等待結束 th1添加元素 th2執行緒結束 th1添加元素 th1添加元素 th1添加元素