В Java volatile имеет такое же общее значение, как и в C. Модель памяти Java (см. Превосходную ссылку в ответе ide) позволяет потокам одновременно «видеть» другое значение для переменных, помеченных как не имеющие значения. неустойчивый. Например:
Тема:
n = 1;
// wait...
n = 2;
Резьбы B и C:
while (true) {
System.out.println(name + ": " + n);
}
Этот вывод разрешен (обратите внимание, что вы не гарантированно строго чередуетесь между B и C, я просто пытаюсь показать здесь «замену» B и C):
C: 1
B: 1
C: 2
B: 1
C: 2
B: 2
Это совершенно отдельно от замка, взятого println
; поток B позволяет видеть n
как 1 даже после того, как C узнает, что это 2. Есть множество очень веских причин для этого, что я не могу притворяться, что полностью понимаю, многие из которых касаются скорости и некоторые, относящиеся к безопасности.
Если он изменчив, вы гарантированно (кроме блокировки println
, которую я пока проигнорирую), что B и C оба "одновременно" увидят новое значение B, как только оно отправлено.
Вы можете использовать volatile
с static
, потому что они влияют на разные вещи. volatile
приводит к тому, что изменения "реплицируются" во все потоки , которые используют эту переменную, прежде чем они ее используют, в то время как static
совместно использует одну переменную для всех классов , которые используют эту переменную. переменная. (Это может немного сбить с толку тех, кто плохо знаком с потоками в Java, потому что каждый Thread
реализован как class
.)