Reputation: 1
I have recently begun to understand how the Java Memory Model works (I don't fully yet).
I now understand that if I have non-final, non-volatile fields in my classes then it is possible for the value of those fields to not be immediately visible to other threads post construction e.g.
public class Example {
Object a;
Object b;
public Example() {
this.a = new Object();
this.b = new Object();
}
}
Example e = new Example();
// now imagine we are in another thread
e.a // could this in theory be null?
e.b // could this in theory be null?
What I'm not sure about is weather if I add a third volatile variable and set it at the end will the writes to a
and b
be guaranteed to be visible to other threads?
public class Example2 {
Object a;
Object b;
volatile Object c;
public Example2() {
this.a = new Object();
this.b = new Object();
this.c = new Object();
}
}
// some where else
Example2 e2 = new Example2();
// are e2.a and e2.b guaranteed to be visible to all other threads? I know (e2.c will be)
This is not something I particularly want to use but I want to understand what would happen in this case.
Upvotes: 0
Views: 93
Reputation: 5165
The constructor runs in a single thread and the instance is not "visible" to other threads until the constructor completes.
So, in this example, a
and b
will only be seen in other threads as null if they are subsequently set to null post-constructor.
The volatile
keyword addresses possible optimizations in which a thread may continue to use an old value for a field after it changes on another thread due to local caching of the value. By adding volatile
to the field, such optimizations are disabled.
By the way, if there's a need to synchronize across threads, using volatile fields is not ideal. Using atomic classes or other constructs from java.util.concurrent
is advisable.
Upvotes: 1