Let's say I have a volatile reference c to MyClass, and MyClass has an integer field x. If one thread changes the value of x, will the new value be guaranteed visible to all other threads, or does x have to be volatile too?
In other words, is the example below guaranteed to print 2?
public class MyClass {
private static volatile MyClass c;
private int x = 1;
public static void main(String[] args) {
c = new MyClass();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
c.x = 2;
}
});
thread.start();
try {
thread.join();
System.out.println(c.x);
} catch (InterruptedException ex) {
//
}
}
If not, what if I want to manipulate an object whose source code I don't control, such as a Collection? How can I ensure that changes to the Collection object are visible to all threads?
For your first question, yes. Volatile makes sure that writes to the
volatile
field are seen by other threads' read operations. It doesn't cascade however, so volatile doesn't fit into all use cases (i.e. just because a reference is volatile doesn't mean all the fields of the referred object would magically become volatile).In most cases you need to
synchronize
the access to make sure that all writes are seen by subsequent reads.