Следующий класс:
class Pizza {
Ingredients ingredients;
Price price;
public setIngredients(Ingredients ing) {
if (ingredients != null) {
throw new IllegalStateException();
}
ingredients = ing;
return this;
}
public setPrice(Price p) {
if (price != null) {
throw new IllegalStateException();
}
price = p;
return this;
}
}
может использоваться в шаблоне компоновщика, и после его построения он эффективно неизменен , поскольку каждое свойство может быть установлено только один раз.То есть:
Pizza pizza = new Pizza().setIngredients(something).setPrice(somethingelse);
Однако Pizza
не является поточно-ориентированным: нет никаких гарантий, что нить B увидит ингредиенты, которые были добавлены в нить A. Есть несколько способов исправить это:
- Зарегистрировать
final
.Но тогда вы не можете использовать шаблон построителя. - Синхронизировать доступ к членам.Но это кажется пустой тратой, потому что они написаны только один раз.
- Сделайте их
volatile
.Чувствует себя бесполезно, как синхронизация. - Использование
AtomicReference
. - И т. Д.?
Мой вопрос: как лучше всего сказать JVM, чточлен класса не изменится после вызова какого-либо метода?Должен ли я просто синхронизировать доступ к нему и верить, что JVM оптимизирует блокировку?Это просто ощущение пустоты, потому что я знаю , что член должен вести себя как final
после его установки.Нет ли лучшего решения?