Allow me to start by clarifying that volatile variables will not solve problems like the thread-safe counter that we are trying to implement. Nevertheless, volatile variables can be used in some scenarios as a simple solution when we need information to be shared among threads.
On the JVM, each thread may contain a cached copy of any non-volatile variable. This cache is not expected to be in sync with the actual value of the variable at all times. So changing a shared state in a thread will not be visible in other threads until the cache is updated.