It is possible for each thread to have a local
stack and maintain copies of some variables there. If you define a variable as volatile, it tells
the compiler not to do any optimizations that would remove reads and writes that keep the
field in exact synchronization with the local data in the threads. In effect, reads and writes go
directly to memory, and are not cached, volatile also restricts compiler reordering of
accesses during optimization.
Basically, you should make a field volatile if that field could be simultaneously accessed by
multiple tasks, and at least one of those accesses is a write. For example, a field that is used
as a flag to stop a task must be declared volatile; otherwise, that flag could be cached in a
register, and when you make changes to the flag from outside the task, the cached value
wouldn’t be changed and the task wouldn’t know it should stop.