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.
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.