When not to use volatile?

1.3k views Asked by At

Is there ever a scenario when we won't use volatile for class member of an object shared between threads? My understanding is that volatile keyword ensures that the object value is not cached by thread but always read from memory, but not marking it volatile doesn't mean that it will always be thread cached. So my question is, can we guarantee anything by not marking such a class as volatile, or will the code be open to random behavior?

EDIT: I understand that using volatile for everything doesn't guarantee the correctness of my logic whatsoever. My question is more of a theoretical nature and is my attempt at understanding the Java Memory Model.

3

There are 3 answers

2
Denis Borovikov On BEST ANSWER

First of all you should not explain concurrency in terms of caches. Since version 2 java memory model is more formal and has weaker requirements. So, it is all about happens-before order.

if you need concurrent access to some variable you have to order writes and reads by happens-before. This is most import thing. Volatile is just one of implementations of this ordering.

So, instead of volatile you can use any operation with happens-before semantic. From JLS:

  • An unlock on a monitor happens-before every subsequent lock on that monitor.

  • A call to start() on a thread happens-before any actions in the started thread.

  • All actions in a thread happen-before any other thread successfully
    returns from a join() on that thread.

  • The default initialization of any object happens-before any other
    actions (other than default-writes) of a program.

2
Lawrence Aiello On

If you don't declare a variable as volatile, and don't do any sort of mutex locking before it is accessed, then yes you always expose yourself to unpredictable behavior and race conditions/deadlocking.

1
Fabian Barney On

At least immutable objects never need any synchronization of any kind. So using volatile for fields of immutable classes does not make sense.