Spec-Zone .ru
спецификации, руководства, описания, API
|
Ошибки непротиворечивости памяти происходят, когда у различных потоков есть непоследовательные представления того, что должно быть теми же самыми данными. Причины ошибок непротиворечивости памяти сложны и вне контекста этого учебного руководства. К счастью, программист не нуждается в подробном понимании этих причин. Все, что необходимо, является стратегией ухода от них.
Ключ к уходу от ошибок непротиворечивости памяти понимает происхождение - перед отношением. Это отношение является просто гарантией, что записи памяти одним определенным оператором видимы к другому определенному оператору. Чтобы видеть это, рассмотрите следующий пример. Предположите простое int
поле определяется и инициализируется:
int counter = 0;
counter
поле совместно используется двумя потоками, A и B. Предположите поток инкременты counter
:
counter++;
Затем, вскоре после этого, распараллельте B, распечатывает counter
:
System.out.println(counter);
Если бы эти два оператора были выполнены в том же самом потоке, было бы безопасно предположить, что распечатанное значение будет "1". Но если эти два оператора выполняются в отдельных потоках, распечатанное значение могло бы хорошо быть "0", потому что нет никакой гарантии, которые распараллеливают изменение А к counter
будет видимо, чтобы распараллелить B — если программист не установил происхождение - перед отношением между этими двумя операторами.
Есть несколько действий, которые создают, происходит - перед отношениями. Один из них является синхронизацией, как мы будем видеть в следующих разделах.
Мы уже видели два действия, которые создают, происходит - перед отношениями.
Thread.start
, у каждого оператора, у которого есть происхождение - перед отношением с тем оператором также, есть происхождение - перед отношением с каждым оператором, выполняемым новым потоком. Эффекты кода, который привел к созданию нового потока, видимы к новому потоку.Thread.join
в другом потоке, чтобы возвратиться, затем у всех операторов, выполняемых завершенным потоком, есть происхождение - перед отношением со всеми операторами после успешного соединения. Эффекты кода в потоке теперь видимы к потоку, который выполнял соединение.Для списка действий, которые создают, происходит - перед отношениями, обратитесь к Сводной странице java.util.concurrent
пакет..