У меня возникают трудности с пониманием барьеров памяти и когерентности кэша в Java и как эти понятия относятся к массивам.Неустойчивые массивы и барьеры памяти и видимость в Java
У меня есть следующий сценарий, в котором один поток изменяет массив (как ссылку на него, так и одно из его внутренних значений), а другой поток читает из него.
int[] integers;
volatile boolean memoryBarrier;
public void resizeAndAddLast(int value) {
integers = Arrays.copyOf(integers, integers.size + 1);
integers[integers.size - 1] = value;
memoryBarrier = true;
}
public int read(int index) {
boolean memoryBarrier = this.memoryBarrier;
return integers[index];
}
Мой вопрос, означает ли это то, что я думаю, что это делает, то делает «издательство» на memoryBarrier
и впоследствии многочасовое чтение переменной силы действие кэш-когерентной и убедитесь, что читатель нить действительно получить как Последняя ссылка на массив и правильное базовое значение по указанному индексу?
Я понимаю, что ссылка на массив не должен быть объявлен volatile
, оно должно быть достаточно, чтобы заставить действие кэш-когерентности, используя любой летучий поле. Правильно ли это рассуждение?
EDIT: существует ровно одна нить писателя и множество потоков считывателей.
Мой сценарий очень специфичен, и я не могу вдаваться в подробности, но на самом деле мне не нужна безопасность потоков в классическом смысле, потому что нить читателя никогда не сможет запросить индекс, который ранее не был опубликован в массив. Что происходит, так это: читатель всегда знает максимальный доступный индекс, но он не знает базового значения этого индекса. Будет ли мой код гарантировать, что читатель всегда получает ** как ** последнюю ссылку на массив ** и ** базовое значение в этом индексе (вместо устаревших значений)? Это проблема видимости, а не безопасность потоков как таковая. – maxim1
Не знаете, каково ваше различие между видимостью и безопасностью потоков; обычно не гарантированная видимость считается нить-небезопасной и наоборот. Ваша программа содержит гонку, как я описал, а это означает, что вам не гарантировано наблюдать как последнюю ссылку на массив, так и значение в индексе. Я добавляю больше кода, чтобы показать вам правильную идиому для безопасной публикации. –
Упс ... другой ответ уже сделал это. Он даже решил использовать одно и то же имя var :) –