Java線程間如何通信(五)


1、簡述

線程是操作系統中獨立的個體,但這些個體如果不經過特殊的處理就不能稱為一個整體。
使線程之間進行通信后,在大大提高CPU利用率的同時還會使開發人員對各個線程任務在處理的過程中進行有效的把控。

2、如何實現線程間通信

2.1、等待(wait)/通知機制(notify)

方法 wait() 說明

方法wait()的作用是使當前執行的線程進行等待,wait() 方法是Object 類的方法,該方法用來將當前線程處於預執行狀態,並且在調用wait()方法的代碼處停止執行,直到接到通知或被終止。

在調用wait()之前,線程必須獲得對象的鎖,即只能在同步方法或代碼塊中調用wait()方法。在執行wait()方法后,當前線程釋放鎖。

如果 調用 wait() 時 沒有持有適當的鎖,則拋出IllegalMonitorStateException, 它是 RuntimeException 的 一個 子類。

方法 notify()說明

notify()方法在調用前,線程也必須獲得該對象的鎖,否則會拋出 IllegalMonitorStateException。該方法用來通知哪些等待該對象鎖的其它線程,如果有多個線程等待,則有線程規划器隨機挑選一個 wait 中的線程,對其發出notify 通知並使它准備回去該對象的鎖。

在執行notify() 方法后,當前線程不會馬上釋放對象鎖,要等待執行notify() 方法的線程執行完畢后,當前線程才會真正釋放鎖。

等待/通知機制總結:

wait()方法可以使調用該方法的線程釋放共享資源的鎖,然后從運行狀態退出, 進入 等待隊列,直到被再次喚醒。

notify() 方法可以隨機喚醒一個等待隊列中的線程,並使該線程退出等待隊列, 進入 可運行狀態,也就是 notify()方法僅通知“ 一個” 線程。

notifyAll()方法可以使所有正在等待隊列中的全部線程 從等待狀態退出, 進入可運行狀態。 此時,優先級最高的那個線程最先執行,但也有可能隨機執行, 因為 這要取決於JVM虛擬機的實現。

2.2、使用方法join

在很多情況下,主線程創建並啟動子線程,如果子線程中要進行大量耗時運算,主線程往往早於子線程結束之前結束。這時如果主線程想等待子線程完成之后再結束,比如子線程處理一個數據,主線程要取得子線程的結果進行計算,就要用到join()方法了。

1、join()方法與 synchronized 的區別是:

join()方法內部使用 wait()方法進行等待,而synchrinized 關鍵字使用的是對象監視器原理實現同步。

2、join()方法與sleep()方法的區別:

join()方法內部是使用wait()方法來實現,所以join()方法具有釋放鎖的特點,而sleep()方法只是釋放了CPU資源,但是不釋放鎖。

2.3、使用ThreadLocal

變量值得共享可以使用 publict static 變量的形式,所有的線程都使用同一個變量。如果每一個線程都有自己的共享變量該如何解決呢?JDK中提供了ThreadLocal 正式為了解決這樣的問題。類 ThreadLocal 主要解決的是每個線程都可以擁有自己線程內的共享變量。

ThreadLocal 主要解決的是線程之間的隔離性,每個線程都有自己獨有的值,互不干擾,同時該特性在父子關系的線程中也有效。

2.4、使用InheritableThreadLocal

使用類InheritableThreadLocal 可以在子線程中取得父線程繼承下來的值。

但在使用類InheritableThreadLocal 時需要注意一點,如果子線程在取得值得同時,主線程將其中的值進行了修改,那么子線程取到的值還是舊值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM