Хотя я чувствую, что private final
, вероятно, должно было бы быть значением по умолчанию для полей и переменных с ключевым словом, таким как var
, что делает его изменчивым, с использованием volatile, когда вам это не нужно,
- многомедленнее, часто примерно в 10 раз медленнее.
- обычно не обеспечивает необходимую вам безопасность потоков, но может затруднить поиск таких ошибок, уменьшив вероятность их появления.
- в отличие от
final
который улучшает ясность, говоря, что это не должно быть изменено, использование volatile
, когда это не нужно, может привести к путанице, поскольку читатель пытается выяснить, почему он стал изменчивым.
если поле должно быть изменено (указать на другой объект, обновить значение примитива), то поле должно быть изменчивым, чтобы все остальные потоки работали с новым значением.
Хотя это хорошо для чтения, рассмотрим этот тривиальный случай.
volatile int x;
x++;
Это не поточно-ориентированный.Так же как и
int x2 = x;
x2 = x2 + 1; // multiple threads could be executing on the same value at this point.
x = x2;
Хуже всего то, что использование volatile
затруднит поиск такого рода ошибки.
С точки зрения yshavit, обновление нескольких полей сложнееvolatile
например HashMap.put(a, b)
обновляет несколько ссылок.
Недостаточно просто синхронизации методов, обращающихся к указанному полю, поскольку они могут возвращать кэшированное значение.
synchronized дает вам все гарантии памяти volatile
и более, поэтому он значительно медленнее.
ПРИМЕЧАНИЕ. Просто synchronized
- для каждого метода тоже не всегда достаточно.StringBuffer
синхронизирует каждый метод, но он хуже, чем бесполезный в многопоточном контексте, так как его использование может быть подвержено ошибкам.
Слишком легко предположить, что достижение безопасности потока похоже на разбрызгивание волшебной пыли,добавьте немного волшебной безопасности, и ваши ошибки исчезнут.Проблема в том, что безопасность ниток больше похожа на ведро с множеством отверстий.Заткните самые большие дыры, и ошибки могут исчезнуть, но если вы не закроете их все, у вас не будет безопасности потоков, но это может быть сложнее найти.
С точки зрения синхронизации против изменчивости, этосостояния
Другие механизмы, такие как чтение и запись энергозависимых переменных и использование классов в пакете java.util.concurrent, предоставляют альтернативные способы синхронизации.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html