1. 程式人生 > >JAVA溫習:多執行緒同步的方法

JAVA溫習:多執行緒同步的方法

1  wait方法:
        該方法屬於Object的方法,wait方法的作用是使得當前呼叫wait方法所在部分(程式碼塊)的執行緒停止執行,並釋放當前獲得的呼叫wait所在的程式碼塊的鎖,並在其他執行緒呼叫notify或者notifyAll方法時恢復到競爭鎖狀態(一旦獲得鎖就恢復執行)。
        呼叫wait方法需要注意幾點:
        第一點:wait被呼叫的時候必須在擁有鎖(即synchronized修飾的)的程式碼塊中。
        第二點:恢復執行後,從wait的下一條語句開始執行,因而wait方法總是應當在while迴圈中呼叫,以免出現恢復執行後繼續執行的條件不滿足卻繼續執行的情況。
        第三點:若wait方法引數中帶時間,則除了notify和notifyAll被呼叫能啟用處於wait狀態(等待狀態)的執行緒進入鎖競爭外,在其他執行緒中interrupt它或者引數時間到了之後,該執行緒也將被啟用到競爭狀態。
        第四點:wait方法被呼叫的執行緒必須獲得之前執行到wait時釋放掉的鎖重新獲得才能夠恢復執行。

2  notify方法和notifyAll方法:
        notify方法通知呼叫了wait方法,但是尚未啟用的一個執行緒進入執行緒排程佇列(即進入鎖競爭),注意不是立即執行。並且具體是哪一個執行緒不能保證。另外一點就是被喚醒的這個執行緒一定是在等待wait所釋放的鎖。
        notifyAll方法則喚醒所有呼叫了wait方法,尚未啟用的程序進入競爭佇列。

3 synchronized關鍵字:
        第一點:synchronized用來標識一個普通方法時,表示一個執行緒要執行該方法,必須取得該方法所在的物件的鎖。
        第二點:synchronized用來標識一個靜態方法時,表示一個執行緒要執行該方法,必須獲得該方法所在的類的類鎖。
        第三點:synchronized修飾一個程式碼塊。類似這樣:synchronized(obj) { //code.... }。表示一個執行緒要執行該程式碼塊,必須獲得obj的鎖。這樣做的目的是減小鎖的粒度,保證當不同塊所需的鎖不衝突時不用對整個物件加鎖。利用零長度的byte陣列物件做obj非常經濟。

4 atomic action(原子操作):
        在JAVA中,以下兩點操作是原子操作。但是c和c++中並不如此。
        第一點:對引用變數和除了long和double之外的原始資料型別變數進行讀寫。
        第二點:對所有宣告為volatile的變數(包括long和double)的讀寫。
        另外:在java.util.concurrent和java.util.concurrent.atomic包中提供了一些不依賴於同步機制的執行緒安全的類和方法。


5 一個例子,該例子模仿多人存取同一個賬戶: