Когда использовать volatile vs synchronization в многопоточности в java?
Когда использовать волатированное ключевое слово vs для синхронизации в многопоточности?
Ответы
Ответ 1
Используйте volatile
, чтобы гарантировать, что каждый доступ для чтения к переменной увидит последнее значение, записанное в эту переменную. Используйте synchronized
, когда вам нужно, чтобы значения были стабильными для нескольких инструкций. (Обратите внимание, что это не обязательно означает несколько операторов: одно выражение:
var++; // NOT thread safe!
не является потокобезопасным, даже если var
объявлен volatile
. Вам нужно сделать это:
synchronized(LOCK_OBJECT){var++;}
См. здесь для хорошего резюме этой проблемы.
Ответ 2
Volatile только гарантирует, что операция чтения всегда дает последнее состояние из памяти по потокам. Тем не менее, он не обеспечивает безопасность записи/порядок операций, т.е. Два потока могут обновлять изменчивую переменную в любом случайном порядке. Также он не гарантирует, что несколько операций над переменной являются атомарными.
Однако синхронизированный блок обеспечивает новейшую безопасность и безопасность записи. Кроме того, доступ и обновление переменной являются атомарными внутри синхронизированного блока.
Вышеприведенное, однако верно, , только если все доступ/обновления к рассматриваемой переменной используют один и тот же объект блокировки, так что ни разу несколько потоков получают доступ к переменной.
Ответ 3
Это довольно широкий вопрос. Лучший ответ, который я могу дать, - это использовать synchronized
при выполнении нескольких действий, которые должны быть видны другими потоками как встречающиеся атомарно: либо все, либо ни одно из шагов не было выполнено.
Для одного действия volatile
может быть достаточно; он действует как барьер памяти для обеспечения видимости изменения для других потоков.
Ответ 4
Volatile не получает блокировку, он использует базовую архитектуру ЦП для обеспечения видимости во всех потоках после записи.