Если вам нужно спросить, используйте замки. volatile
может быть полезно в некоторых случаях, но это очень, очень трудно понять правильно. Например:
class Foo {
private volatile int counter = 0;
int Increment() {
counter++;
return counter;
}
}
Если два потока запускают Increment()
одновременно, возможно, что результат будет counter = 1
. Это связано с тем, что компьютер сначала извлечет counter
, добавляет его, а затем сохраняет обратно. Volatile просто заставляет сохранять и загружать данные в определенном порядке относительно других операторов.
Обратите внимание, что synchronized
обычно устраняет необходимость в volatile
- если все обращения к данному полю защищены одним монитором, volatile
никогда не потребуется.
Использование volatile
для создания алгоритмов без блокировки очень, очень сложно; придерживайтесь synchronized
, если у вас нет веских доказательств того, что это уже слишком медленно, и вы не провели детальный анализ алгоритма, который вы планируете реализовать.