Нужно синхронизировать настройку булевых членских варов?

Привет всем, я работаю над некоторым кодом, который я унаследовал. Похоже, что один поток устанавливает логическую переменную-член, а другой поток находится в цикле 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 и что чтение и запись будут синхронизированы