Ответ 1
Ключевое слово synchronized
- это один из способов обеспечения безопасности потоков. Остерегайтесь: там (путь) больше к потокобезопасности, чем взаимоблокировки, или отсутствующие обновления из-за двух потоков, увеличивающих int без синхронизации.
Рассмотрим следующий класс:
class Connection {
private boolean connected;
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
}
Если несколько потоков совместно используют экземпляр Connection
, а один поток вызывает setConnected(true)
, без synchronized
возможно, что другие потоки продолжают видеть isConnected() == false
. Ключевое слово synchronized
гарантирует, что все потоки будут видеть текущее значение поля.
В более технических терминах ключевое слово synchronized
обеспечивает барьер памяти (подсказка: google that).
Более подробно: каждая запись, сделанная перед выпуском монитора (т.е. перед тем, как оставить блок synchronized
), будет гарантирована каждым чтением, сделанным после получения одного и того же монитора (т.е. после ввода блока синхронизации на том же объект). В Java есть что-то, называемое случается-раньше (подсказка: google that), что не так тривиально, как "я написал код в этом порядке, поэтому все будет выполнено в этом порядке". Использование synchronized
- это способ установить связь между событиями и гарантировать, что потоки видят память, как вы ожидали бы от них.
Другим способом достижения тех же гарантий в этом случае было бы исключить ключевое слово synchronized
и пометить поле volatile
. Гарантии, предоставляемые volatile
, заключаются в следующем: все записи, сделанные потоком, прежде чем волатильная запись гарантированно будет видна в потоке после последующего волатильного чтения того же поля.
Как последнее замечание, в этом конкретном случае было бы лучше использовать поле volatile
вместо synchronized
accessors, потому что оба подхода обеспечивают одинаковые гарантии, а подход volatile
-field позволяет одновременный доступ к поле из разных потоков (что может повысить производительность, если версия synchronized
имеет слишком много противоречий).