2009-12-30 8 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); 
} 

Теперь, если соединение, где закрыть между чеком, если заявление и вызов метода, mConnectedThread может быть присвоен нулевой, перед выполнением вызова метода , Это приведет к NullPointerException.

+1

Конечно, не зная больше, соединение все равно может быть закрыто между концом блока синхронизации и фактическим вызовом write(), который теперь может привести к совершенно другой ошибке. И, если ConnectThread обрабатывает write() s после отмены изящества, просто присваивая его локальной переменной, и проверка на null будет еще проще. – PSpeed

1

Всякий раз, когда два потока доступ к тем же данным (здесь переменные mState и mConnectedThread), они должны использовать «барьер памяти», который обеспечивает видимость. По-видимому, здесь важны атомарность mState и mConnectedThread.

Видимость означает, что изменения, сделанные одним потоком, будут видны другому. Оптимизация может привести к кэшированию значения, чтобы изменения были видны только потоку, который их создал. Синхронизация приводит к тому, что любые записи должны отражаться в основной памяти, а каждый считывает обход локальных кешей и делается против основной памяти. Теоретически, без синхронизации один поток может установить mState и mConnectedThread, но другие потоки никогда не смогут «видеть» эти изменения и ждать навсегда, чтобы это условие изменилось.

Атомность означает, что отдельные действия не могут наблюдаться индивидуально. С точки зрения другого потока ни одно из изменений не произошло, или все изменения произошли. Так, например, другой поток никогда не видел, чтобы mState был STATE_CONNECTED, но прочитал mConnectedThread, прежде чем он был назначен.

1

Блокировка необходима для согласованности. Копирование mConnectedThread в отдельную переменную, потому что тогда запись, которая является потенциально длинной, может быть выполнена за пределами блокировки.

+0

Spot the C programmer;) (не проголосовал за вас) –

Смежные вопросы