Предполагая, что:
- Существует только один конкретный поток, который когда-либо устанавливает определенное ссылочное поле (не длинное или двойное, поэтому запись на него является атомарной)
- Есть любое количество потоков, которые могли бы прочитать это же поле
- Слегка устаревшие чтения допустимы (до нескольких секунд).
В этом случае вам нужна изменчивая или AtomicReference или что-то в этом роде?
В этой статье говорится:
Пределы памяти не требуются, если вы строго придерживаетесь принципа одиночной записи.
Кажется, что в случае, когда я описываю, вам действительно не нужно ничего особенного.
Итак, вот тест, который я провел с любопытными результатами:
import org.junit.Test;
public class ThreadTest {
int onlyWrittenByMain = 0;
int onlyWrittenByThread = 0;
@Test
public void testThread() throws InterruptedException {
Thread newThread = new Thread(new Runnable() {
@Override
public void run() {
do {
onlyWrittenByThread++;
} while (onlyWrittenByMain < 10 || onlyWrittenByThread < 10);
System.out.println("thread done");
}
});
newThread.start();
do {
onlyWrittenByMain++;
// Thread.yield();
// System.out.println("test");
// new Random().nextInt();
} while (onlyWrittenByThread < 10);
System.out.println("main done");
}
}
Иногда выполнение этого будет выводить "thread done", а затем зависать вечно. Иногда это заканчивается. Таким образом, поток видит изменения, которые делает основной поток, но, по-видимому, главное не всегда видит изменения, которые делает поток.
Если я вставил систему или Thread.yield или случайный вызов, либо сделайте onlyWrittenByThread volatile, он будет завершен каждый раз (пробовал примерно 10 + раз).
Означает ли это, что сообщение в блоге, приведенное выше, неверно? Что вы должны иметь барьер памяти даже в сценарии с одним сценарием?
Никто не ответил на этот вопрос, поэтому я думаю, что я думаю, что он, вероятно, исправит, что барьер памяти не требуется, но без чего-либо, чтобы создать взаимосвязи между событиями, java-компилятор и точка доступа могут выполнять оптимизацию (например. подъем), который заставит его не делать то, что нужно.