Volatile означает, что мы должны перейти в память, чтобы получить или установить это значение. Если вы не установите volatile, скомпилированный код может долго хранить данные в регистре.
Это означает, что вы должны пометить переменные, которые вы разделяете между потоками, как изменчивые, чтобы у вас не возникало ситуаций, когда один поток начинает изменять значение, но не записывает свой результат до появления второго потока и пытается прочитайте значение.
Volatile - подсказка компилятора, которая отключает некоторые оптимизации. Выходная сборка компилятора могла бы быть безопасной без него, но вы всегда должны использовать ее для общих значений.
Это особенно важно, если вы НЕ используете дорогостоящие объекты синхронизации потоков, предоставляемые вашей системой - например, у вас может быть структура данных, в которой вы можете сохранить ее действительной с помощью ряда атомарных изменений. Многие стеки, которые не выделяют память, являются примерами таких структур данных, потому что вы можете добавить значение в стек, затем переместить указатель конца или удалить значение из стека после перемещения указателя конца. При реализации такой структуры энергозависимость становится критически важной для обеспечения того, чтобы ваши атомарные инструкции действительно были атомарными.