Рассмотрим фрагмент кода Java Параллелизм в Practice-Немного прояснение летучим ключевое слово
// Unsafe publication
public Holder holder;
public void initialize(){
holder = new holder(42);
}
public class Holder{
private int n;
public Holder(int n) {
this.n = n;
}
public void assertSanity(){
if (n != n)
throw new AssertionError("This statement is false.");
}
}
Одним из решений, предложенных автором книги -
public static Holder holder = new Holder(42);
И если единственное требование состояло в том, чтобы предотвратить AssertionError
, тогда это также будет работать нормально
private final int n;
Мой вопрос прослеживание на комментарий по этому StackOverflow thread Джон Vint-
На самом деле, объявляя поле член летучего еще оленья кожа гарантировать публикации до держателя быть видны. Вы можете посмотреть на Частный метод ConcurrentHashMap readUnderLock, в котором это учитывает этот нюанс . Хотя объявление держателя как изменчивое.
Выражаясь простыми словами, он предлагает, тем самым 2 вещей:
public volatile Holder holder;
public void initialize(){
holder = new holder(42);
}
ли вышеуказанное решение будет работать отлично? Если ссылка на объект объявлена изменчивой, обеспечивает ли она безопасную публикацию объекта? Массивы тоже объекты. Объявление ссылки на массив не делает потоки элементов безопасными.
И почему это не будет работать, как было предложено
автораpublic class Holder {
private volatile int n;
объявления поля члена летучей еще оленья кожа гарантии публикации до держателя быть видимый
Несмотря на то, как член поле было объявлено летучим, его гарантируют, что условие n != n
будет всегда false, и, следовательно, нет AssertionError
. Пожалуйста, предложите.
Спасибо. Но автор не ошибается в этом конкретном случае. –
@ShirgillFarhanAnsari Я согласен, в целом 'volatile' не предоставляет вам необходимые гарантии, но в этом конкретном случае это будет работать. –
Еще раз спасибо, но не получил вашу точку за второй фрагмент кода 'Holder h = holder;' // читаем барьер. Пожалуйста, дополните. –