Structured Lock (intrinsic lock / monitors)
這就是synchronized keyword,特徵就是thread mutual exclusion是implicit達成,沒有任何一個explicit lock出現。每個Java object都有一個intrinsic lock,一個thread要對此object獲得mutual exclusive right的話,就要acquire這個object的intrinsic lock:
thread X: acquire A's lock ----- (own the lock) ------> release A's lock
thread Y: --------------block when try to acquire A's lock-------acquire A's lock ..........
一個thead 如何acquire object A's intrinsic lock?
1. 呼叫A的synchronized instance method會自動獲得A's lock,在method returns/throws exceptions 會自動release lock。如果是synchronized class method,則獲得此class的關聯Class object的instrinsic lock,保護static fields。2. 使用 synchronized(A),這可以放在比較fine-grained小區域保護範圍。
Reentrant Synchronization
Java lock可以被同一個thread acquire多次,這保護這個thread不會自己把自己block住了,所以不用害怕會發生這樣的事。不過既然稱為structured lock,則acquire lock的順序會配合上相反順序的release。Wait / Notify
假設以下的程式在等待一個flag joy被設為true:public void guardedJoy() { // Simple loop guard. Wastes // processor time. Don't do this! while(!joy) {} System.out.println("Joy has been achieved!"); }
某個thread要是執行這個method,就會在while loop裡面一直等待,但是OS還是會分配CPU resource來執行這個while loop,等於浪費CPU資源。如果把此method加上synchronized keyword,此時可以呼叫此object instance 的wait()來suspend這個thread:
public synchronized void guardedJoy() { // This guard only loops once for each special event, which may not // be the event we're waiting for. while(!joy) { try { wait(); //the thread releases the lock and is suspended } catch (InterruptedException e) {} } System.out.println("Joy and efficiency have been achieved!"); }此thread被suspended,只有當某個Interrupt發生才會resume,例如其他的thread呼叫notifyAll,但是這不一定是我們在等待的interrupt (e.g. 不一定是joy被改變的事件),所以一定要在檢查condition的loop中呼叫wait(),才能在interrupt發生的時候檢查condition來決定是否繼續wait。
為什麼要把此method加上synchronized? 其實是因為要呼叫此object的wait() method必須要acquire 此object's intrinsic lock。
一旦呼叫wait(),則thread會release此object lock然後suspended。
某個method會讓另一個thread acquire lock並且產生interrupt來notify所有suspended threads:
public synchronized notifyJoy() { joy = true; notifyAll(); }
被interrupt甦醒的thread 會重新獲得這個object's lock (因為另一個thread在method returns就release lock),繼續在while loop中檢查是否要繼續wait。
沒有留言:
張貼留言