Применение этого модификатора к полю класса означает:
- Значение этого поля никогда не будет кэшироваться потоками в свою локальную область памяти. Все чтения и записи будут идти напрямую в "главную" память, т.е. ту, в которой и размещено поле класса
- Доступ к переменной действует как будто бы она была заключена в блок synchronized, который синхронизируется по самому полю
Поясним первый пункт. Java позволяет потокам, которые имеют доступ к зашаренным переменным сохранять локальные копии этих переменных в своей области памяти для более эффективной работы. Точнее, это позволяет сделать саму реализацию многопоточности более эффективной. Эти "рабочии копии" должны быть синхронизированы с мастер-копией только лишь в заранее определенных точках, которые обусловлены синхронизацией - а именно, когда объект лочится (locks) и разлочивается (unlocks). Как правило, чтобы убедиться, что разделяемая переменная целостно и надежно (reliably) обновляется, поток должен быть уверенным, что он имеет эксклюзивный доступ к такой переменной. Это делается получением лока на переменную, который и обеспечивает взаимное исключение для доступа к этой переменной.
Для пояснения второго пункта приведем табличку для сравнения volatile и synchronized. Не зря во втором пункте использовано слово "как будто": Доступ к переменной действует как будто бы она была заключена в блок synchronized. Т.к. явно в коде монитор, по которому синхронизируется доступ к переменной, не используется....
Итак, табличка:
Свойство | synchronized | volatile |
Тип переменной | Только объект | Объект или примитив |
Разрешен ли null | нет | да |
Может ли быть блокировка | да | нет |
Когда происходит синхронизация | Когда явно происходит вход в блок synchronized | Каждый раз при доступе к переменной |
Дополнительно см: The volatile keyword in Java
Чётко, автору спасибо!
ОтветитьУдалитьСпасибо!
ОтветитьУдалитьСпасибо!
ОтветитьУдалитьСпасибо большое,коротко и ясно!
ОтветитьУдалить