Предположим, у меня есть поле, к которому обращаются одновременно, и оно читается много раз и редко записывается в него.
public Object myRef = new Object();
Допустим, поток T1 будет устанавливать myRef другое значение раз в минуту, а N другоеПотоки будут читать myRef миллиарды раз непрерывно и одновременно. Мне только нужно, чтобы myRef в конечном итоге был виден всем потокам.
Простым решением было бы использование AtomicReference или просто изменчивого типа, как это:
public volatile Object myRef = new Object();
Тем не менее, afaik volatile чтения действительно вызываетстоимость исполнения. Я знаю, что это незначительно, это больше похоже на то, что мне интересно, чем на то, что мне действительно нужно. Так что давайте не будем беспокоиться о производительности и предположим, что это чисто теоретический вопрос.
Итак, вопрос сводится к следующему: Есть ли способ безопасно обойти энергозависимые чтения для ссылок, в которые редко пишутся, выполняячто-то на сайте записи?
После некоторого чтения, похоже, что барьеры памяти могут быть тем, что мне нужно. Поэтому, если бы существовала такая конструкция, моя проблема была бы решена:
- Запись
- Invoke Barrier (sync)
- Все синхронизировано, и все потоки увидятновое значение. (без постоянных затрат на чтение сайтов, он может быть устаревшим или нести единовременную стоимость, поскольку кэши синхронизируются, но после этого все возвращается к обычному полю до следующей записи).
Isесть такая конструкция в Java или вообще? На данный момент я не могу не думать, что если бы что-то подобное существовало, оно было бы уже включено в атомарные пакеты гораздо более умными людьми, которые их поддерживали. (Непропорционально частое чтение против записи, возможно, не подходило для этого?) Так что, может быть, в моем мышлении что-то не так, и такая конструкция вообще невозможна?
Я видел, как некоторые примеры кода используют 'волатильным »для аналогичной цели, используя его до контракта. Существует отдельное поле синхронизации, например:
public Object myRef = new Object();
public volatile int sync = 0;
и при написании темы / сайта:
myRef = new Object();
sync += 1 //volatile write to emulate barrier
Я не уверен, что это работает, и некоторые утверждают, что это работает только на архитектуре x86. После прочтения связанных разделов в JMS, я думаю, что гарантированно сработает только в том случае, если эта изменчивая запись связана с изменчивым чтением из потоков, которым необходимо увидеть новое значение myRef. (Так что не избавляйтесь от изменчивого чтения).
Возвращаясь к моему первоначальному вопросу;Это вообще возможно? Возможно ли это на Java? Возможно ли это в одном из новых API в Java 9 VarHandles?