Нужно синхронизировать настройку булевых членских варов?
Привет всем, я работаю над некоторым кодом, который я унаследовал. Похоже, что один поток устанавливает логическую переменную-член, а другой поток находится в цикле while, проверяя его. Будет ли это работать нормально или я должен его изменить, чтобы использовать синхронизированные геттеры или сеттеры в булевом var?
Ответы
Ответ 1
В случае чтения и записи примитива, такого как bool или int, объявляющего их как volatile, будет много. Когда один поток прочитает другой поток, он закончил бы запись. Переменная никогда не будет находиться в недопустимом состоянии.
Вероятно, справедливо сказать, что в целом ключевое слово volatile в Java плохо документирован, плохо разбирается и редко используется. Делать что еще хуже, его формальное определение фактически изменилось с Java 5. По существу, volatile используется, чтобы указать, что значение переменной будет быть изменен различными потоками.
Объявление изменчивой переменной Java означает:
- Значение этой переменной будет никогда не кэшироваться нить-локально: все читать и писать будет прямо "основная память";
- Доступ к переменной действует как хотя он заключен в синхронизированный блок, синхронизированный по сам по себе.
Мы говорим: "действует как бы" во второй точке, потому что программисту по крайней мере (и, вероятно, в большинстве реализаций JVM), фактического заблокированный объект.
http://www.javamex.com/tutorials/synchronization_volatile.shtml
Ответ 2
Почти наверняка вам нужно будет добавить блокировку на более высоком уровне. Простое добавление synchronized
вокруг одиночного доступа к полям редко помогает. Композитные операции не будут потокобезопасными, если операции с компонентами независимо поточно защищены.
В качестве примера рассмотрим удаление содержимого потокобезопасного документа. В документе предусмотрены две соответствующие поточно-безопасные операции: удаление содержимого между двумя индексами и операция длины. Таким образом, вы получаете длину и удаляете от нуля до длины, верно? Ну, там гонка, поскольку документ может изменить длину между чтением длины и удалением содержимого. Невозможно сделать операцию поточной безопасностью с учетом операций. (Пример из Swing Text.)
Ответ 3
Если вы используете java 1.5+, вы должны использовать Condition примитив синхронизации.
Если вы следуете ссылке, у нее есть хороший пример того, как ее использовать.
Ответ 4
Не гарантируется работа, если он является простым логическим, один из потоков может не увидеть обновленное логическое значение из-за модели памяти java, вы можете
Имейте в виду, что ни один из них не может "работать", если поток, читающий это логическое значение, зависит от предыдущего значения логического значения - он может пропустить изменения в этом булевом, например
Резьба1:
while(foo.myVolatileBoolean) {
...
}
Резьба2:
foo.myVolatileBoolean = false; //thread 1 might never catch thisone.
...
foo.myVolatileBoolean = true;
Если это проблема, и вам нужно следить за изменениями в логическом режиме, подумайте об использовании wait()/notify() или Condition
Ответ 5
Я бы предположил, что логическое значение будет объявлено volatile и что чтение и запись будут синхронизированы