Предполагая:Если у вас только один поток писем, вам когда-нибудь нужен специальный параллелизм?
- Существует только один конкретный поток, который когда-либо задает определенное ссылочное поле (не длинное или двойного, так пишет к нему атомарный)
- Есть любое количество потоков, которые могли бы прочитать, что это же поле
- Слегка черствый читает приемлемы (до нескольких секунд)
в этом случае вам нужно летучего или AtomicReference или что-нибудь подобное?
This article состояния:
барьеры памяти не требуется, если строго придерживаться принципа единого писателя.
Который, кажется, предполагает, что в случае, о котором я описываю, вам действительно не нужно ничего особенного.
Итак, вот тест, который я провел с любопытными результатами:
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.yield или случайный вызов, либо сделайте onlyWrittenByThread изменчивым, он будет завершен каждый раз (проверено более 10 раз).
Означает ли это, что сообщение в блоге, приведенное выше, неверно? Что вы должны иметь барьер памяти даже в сценарии одного писателя?
Никто не ответил на этот вопрос, поэтому я думаю, что, вероятно, правильно, что барьер памяти не требуется, но без создания каких-либо отношений, java-компилятор и точка доступа могут выполнять оптимизацию (например, .), которые сделают это не тем, что нужно.
Вам все равно придется беспокоиться о неполной записи, то есть чтение переменного, когда она была только частично написана. Если записи являются атомарными, вы в порядке. – theglauber
Вам нужно как минимум 'volatile'. Нет никаких гарантий того, что запись в энергонезависимую переменную одним потоком будет невидимой для других потоков. 'volatile' гарантирует это! – fge
@fge, можете ли вы предоставить какую-либо окончательную документацию для этого? Я пытаюсь прочитать главу 17 спецификации, но я не вижу, что поддерживает ваши претензии. Хотя, возможно, это отсутствие утверждения, опровергающего это пункт. – mentics