線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。
在 Java 中,線程等待和通知的實現手段有以下幾種方式:
為什么一個線程等待和通知機制就需要這么多的實現方式呢?
別著急,咱們先來看實現,再來說原因。
Object 類的方法說明:
示例代碼如下:
Object lock = new Object();// 創建線程并執行new Thread(() -> { System.out.println("線程1:開始執行"); synchronized (lock) { try { System.out.println("線程1:進入等待"); lock.wait(); System.out.println("線程1:繼續執行"); Thread.sleep(3000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("線程1:執行完成"); }}).start();Thread.sleep(1000);synchronized (lock) { // 喚醒線程 System.out.println("執行 notifyAll()"); lock.notifyAll();}
Condition 類的方法說明:
示例代碼如下:
// 創建 Condition 對象Lock lock = new ReentrantLock();Condition condition = lock.newCondition(); // lock 下可創建多個 Condition// 加鎖lock.lock();try { // 業務方法...... // 1.進入等待狀態 condition.await(); // 2.喚醒操作 condition.signal();} catch (InterruptedException e) { e.printStackTrace();} finally { lock.unlock();}
LockSupport 類的方法說明:
PS:LockSupport 無需配鎖(synchronized 或 Lock)一起使用。
示例代碼如下:
public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { LockSupport.park(); System.out.println("線程1"); }, "線程1"); t1.start(); Thread t2 = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("喚醒線程1"); LockSupport.unpark(t1); }, "線程2"); t2.start();}
為什么一個線程等待和喚醒的功能需要這么多的實現呢?
// 創建 Condition 對象private Lock lock = new ReentrantLock();// 生產者的 Condition 對象private Condition producerCondition = lock.newCondition();// 本篇內容出自磊哥《Java面試突擊訓練營》 VX:GG_Stone// 消費者的 Condition 對象private Condition consumerCondition = lock.newCondition();
也就是 Condition 是 Object 等待喚醒模型的升級,Object 類可以實現的功能它都能實現,但 Condition 能實現的功能,Object 卻不能實現,這就是 Condition 類存在的必要性。
那問題來了,為什么還有會 Object 的 wait 和 notify 方法呢?因為 Object 類誕生的比較早,也就是說 Condition 和 LockSupport 都是 JDK 后期版本才出現的功能,所以就有了現在這么多線程喚醒和等待的方法了。
本文鏈接:http://www.www.ut100.cn/showinfo-26-77-0.html線程通訊的三種方法!通俗易懂
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 十個可以手動編寫的 JavaScript 數組 API
下一篇: Rust中的高吞吐量流處理