2009-12-30 70 views
1

這裏的同步點是什麼?這種同步的重點是什麼?

爲什麼不只是使用mConnectedThread.write(out)

的代碼片段是從BluetoothChat樣品爲Android (found here)

需要
/** 
* Write to the ConnectedThread in an unsynchronized manner 
* @param out The bytes to write 
* @see ConnectedThread#write(byte[]) 
*/ 
public void write(byte[] out) { 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (mState != STATE_CONNECTED) return; 
     r = mConnectedThread; 
    } 
    // Perform the write unsynchronized 
    r.write(out); 
} 

回答

2

同步,以確保你沒有不一致的狀態。

沒有同步,代碼是:

public void write(byte[] out) { 
    if (mState != STATE_CONNECTED) return; 
    mConnectedThread.write(out); 
} 

現在,如果連接到哪裏if語句檢查和方法調用之間關閉,mConnectedThread可能被指定爲null,方法調用執行前。這將導致NullPointerException

+1

當然,不知道更多的連接仍然可以在同步塊的結束和實際的write()調用之間關閉......現在可能會產生完全不同的錯誤。而且,如果ConnectThread在正常取消後處理write(),那麼簡單地將它分配給一個局部變量並檢查null將是一種更簡單的方法。 – PSpeed 2009-12-30 23:04:54

1

每當兩個線程訪問相同的數據(在這裏,變量mStatemConnectedThread),他們必須使用「記憶障礙」,確保知名度。看起來這裏的mStatemConnectedThread的原子性也很重要。

可視性意味着一個線程所做的更改將對另一個線程可見。優化可能會導致緩存值,以便更改僅對創建它們的線程可見。同步會導致任何寫入都反映在主內存中,並且任何讀取都會繞過本地緩存並針對主內存進行讀取。理論上,如果沒有同步,一個線程可能會設置mStatemConnectedThread,但其他線程可能永遠不會「看到」這些更改,並且會永久等待該條件發生更改。

原子性意味着無法單獨觀察多個動作。從另一個線程的角度來看,沒有發生任何變化,或者發生了所有變化。因此,例如,另一個線程永遠不會看到mStateSTATE_CONNECTED,但在分配之前已讀取mConnectedThread

1

鎖需要一致性。 將mConnectedThread複製到單獨的變量是因爲寫入 - 這是一個可能的長度操作 - 可以在鎖之外完成。

+0

現貨C程序員;)(沒有投票給你) – 2009-12-30 22:30:15