[英]What's the point of this synchronization?
這里的同步有什么意義?
為什么不直接使用mConnectedThread.write(out)
?
代碼片段來自適用於Android的BluetoothChat示例(可在此處找到)
/**
* 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);
}
需要進行同步以確保您沒有不一致的狀態。
沒有同步,代碼將是:
public void write(byte[] out) {
if (mState != STATE_CONNECTED) return;
mConnectedThread.write(out);
}
現在,如果if語句檢查和方法調用之間的連接關閉,則mConnectedThread
可能在方法調用執行之前被賦值為null。 這將導致NullPointerException
。
每當兩個線程訪問相同的數據(這里是變量mState
和mConnectedThread
)時,它們必須使用“內存屏障”來確保可見性。 看來mState
和mConnectedThread
的原子性在這里也很重要。
可見性意味着一個線程所做的更改對另一個線程可見。 優化可能會導致值被緩存,以便更改僅對創建它們的線程可見。 同步導致任何寫入都反映在主內存中,並且任何讀取都會繞過本地緩存並對主內存進行。 理論上,如果沒有同步,一個線程可以設置mState
和mConnectedThread
,但是其他線程可能永遠不會“看到”那些更改,並且永遠等待該條件發生更改。
原子性意味着無法單獨觀察多個動作。 從另一個線程的角度來看,沒有發生任何更改,或者發生了所有更改。 因此,例如,另一個線程永遠不會看到mState
是STATE_CONNECTED
,而是在分配之前讀取mConnectedThread
。
為了保持一致性需要鎖定。 將mConnectedThread復制到單獨的變量是因為寫入 - 這是一個可能的長度操作 - 可以在鎖之外完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.