You need to be a little careful here, as you have chosen two different types in your examples. My general rule is that volatile is best used with booleans and everything else, you probably need some other kind of synchronization mechanism. In C # and java, volatile boolean is very often used, for example. stop a cycle or execution of a task that has visibility from multiple threads:
class Processor { private volatile Boolean _stopProcessing = false; public void process() { do { ... } while (!_stopProcessing); } public void cancel() { _stopProcessing = true; } }
The above will work in C # or java, and in this example, the volatile keyword means that reading in the process method will be from the actual current value, and not from the cached value. The compiler or virtual machine may otherwise allow caching of the value, since the loop does not change _stopProcessing in the process.
So the answer is yes to your first question.
While you can use volatile in int, this only helps if you are only reading or writing a single value. As soon as you do something more complex, such as increasing, you need some other kind of synchronization, such as using locks. In your second example, however, you are still reading the counter value without any synchronization, so you effectively rely on other counter actions that need to be synchronized (for example, with a lock).
In your second example, you would still be better off marking your int as mutable, so you can again be sure that you are getting the current value, not some cached version. However, using volatility alone is not enough, because reading below can overlap with the standard decrement (counter), and not with the correct use of locking.
Matt
source share