1. 程式人生 > >線程如何同步和通訊

線程如何同步和通訊

zed 執行 ava 構造器 基本 指定時間 通訊 訪問 not

線程同步
什麽是線程同步?

線程同步的真實意思恰好相反,其實是“排隊”。當使用多個線程來訪問同一個數據時,非常容易出現線程安全問題(比如多個線程都在操作同一數據導致數據不一致),所以我們用同步機制來解決這些問題。
實現同步機制有兩個方法:

  1. 同步代碼塊:
    synchronized(同一個數據/鎖){} 同一個數據:就是N條線程同時訪問一個數據。
  2. 同步方法:
    public synchronized 數據返回類型 方法名(){}
    同步方法的同步監視器(鎖)是 this 也就是該對象的本身通過使用同步方法,可非常方便的將某類變成線程安全的類。

線程安全的類:

  1. 這個類的對象可以同時被多個線程安全的訪問。
  2. 每個線程都能正常的執行原子操作,得到正確的結果。
  3. 在每個線程的原子操作都完成後,對象處於邏輯上合理的狀態。

註意:synchronized關鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構造器,屬性等。實現同步機制註意以下幾點: 安全性高,性能低,在多線程用。性能高,安全性低,在單線程用。

線程通訊:
為什麽要使用線程通訊?

當使用synchronized 來修飾某個共享資源時(分同步代碼塊和同步方法兩種情況),當某個線程獲得共享資源的鎖後就可以執行相應的代碼段,直到該線程運行完該代碼段後才釋放對該 共享資源的鎖,讓其他線程有機會執行對該共享資源的修改。當某個線程占有某個共享資源的鎖時,如果另外一個線程也想獲得這把鎖運行就需要使用wait() 和notify()/notifyAll()方法來進行線程通訊了。

wait():導致當前線程等待,直到其他線程調用同步監視器的notify方法或notifyAll方法來喚醒該線程。

wait(mills):都是等待指定時間後自動蘇醒,調用wait方法的當前線程會釋放該同步監視器的鎖定,可以不用notify或notifyAll方法把它喚醒。

notify():喚醒在同步監視器上等待的單個線程
notifyAll()方法:喚醒在同步監視器上等待的單個線程

同步鎖

線程同步的基本實現思路還是比較容易理解的。我們可以給共享資源加一把鎖,這把鎖只有一把鑰匙。哪個線程獲取了這把鑰匙,才有權利訪問該共享資源。
但是,現代的編程語言的設計思路都是把同步鎖加在代碼段上。確切的說,是把同步鎖加在“訪問共享資源的代碼段”上。這一點一定要記住,同步鎖是加在代碼段上的。

public static final Object lock1 = new Object(); 

… f1() { 

synchronized(lock1){ // lock1 是公用同步鎖 
  // 代碼段 A 
// 訪問共享資源 resource1 
// 需要同步 
} 
}

  

線程如何同步和通訊