2. Normal Field on an Instance
What must be the value in provider.f
Thread 2 Thread 1
provider = new FinalFieldExample();
<read> provider.f; class FinalFieldExample {
private Object f;
FinalFieldExample() {
f = new Object();
}
}
3. Normal Field on an Instance
What must be the value in provider.f
No guarantee of proper visibility of values by a
read in <f> in Thread 2.
4. Final Field on an Instance
What must be the value in provider.f
Thread 2 Thread 1
provider = new FinalFieldExample();
<read> provider.f; class FinalFieldExample {
private final Object f;
FinalFieldExample() {
f = new Object();
}
}
5. Final Field on an Instance
What must be the value in provider.f
The visibility of values in <f> is guaranteed by
a read in Thread 2.
6. Volatile field on an Instance
What must be the value in provider.f
Thread 2 Thread 1
provider = new FinalFieldExample();
<read> provider.f; class FinalFieldExample {
private volatile Object f = null;
FinalFieldExample() {
f = new Object();
}
}
7. Volatile field on an Instance
What must be the value in provider.f
No guarantee of proper visibility of values in
<f> by a read in Thread 2.
Constructors freeze and the guarantees apply
only to objects with final fields.
An object is considered to be completely
initialized when its constructor finishes.
8. Dereferenced Object in other Thread
Thread 2 Thread 1
Use of s. s = new String()
An implementation detail.
The java.lang.String has private members
char value[]
int offset
int count
int hash
9. Dereferenced Object in other Thread
Broken JMM in JDK 1.4 and earlier.
The immutable object (of java.lang.String as a
real example) has a proper visibility of the
values in internal fields into other threads due
to fixes in JMM since JDK 1.5.
10. Combined Fields on an Instance
What must be the values.
Thread 2 Thread 1
provider = new FinalFieldExample();
<read> provider.f; class FinalFieldExample {
<read> provider.x;
private final Object f;
private Object x;
FinalFieldExample() {
x = new Object();
f = new Object();
}
}
11. Combined Fields on an Instance
What must be the values.
Suppose<provider> is non-final field, non-null.
The value which is set to <x> in the
constructor has improper visibility in Thread 2.
Value assigned to <f> is properly visible to
Thread 2.
Dereference and Memory Chains for the read
of <f> in Thread 2 can pass through any reads
by Thread 2 of a reference to <provider>.
12. Combined Fields on an Instance
What must be the values.
Thread 2 Thread 1
provider = new FinalFieldExample();
<read> provider.f; class FinalFieldExample {
<read> provider.g; private final Object f;
<read> provider.a; private final Object g;
<read> provider.b; private Object a, b, c, d;
<read> provider.c;
<read> provider.d; FinalFieldExample() {
a = new Object();
b = new Object();
f = new Object();
c = new Object();
g = new Object();
d = new Object();
}
}
13. Combined Fields on an Instance
What must be the values.
Values in a, b, c, and d have no guarantee to
be properly visible by a read in Thread 2.
(see previous slide)
Since the <f> and <g> are final, their
operations cannot be reordered with other.
Operations on <a>, <b> can be reordered.
<c> is always between <f> and <g>.
<d> stays behind <g>
14. Reflection on Final Field
What must be the value in f
DO NOT USE IN CONCURRENT CODE
private final Object f = ;
getClass().getField("f").set(this, new Object());
return f;
15. Reflection on Final Field
What must be the value in f
If a final field is initialized to a compile-time
constant in the field declaration, changes to
the final field may not be observed, since uses
of that final field are replaced at compile time
with the compile-time constant.
16. Aggressive optimization of final fields.
Within a thread, it is permissible to reorder
reads of a final field with calls to methods that
may change final fields via reflection.
Reflection can be used to change final fields
after the constructor for the object completes.
17. Aggressive optimization of final fields.
A method which only returns a value held by
final field will be inlined with compile-time
value into methods caller code;
Static methods and private instance methods
are considered final and inlined;
Method code smaller than 35 bytes in byte
code used to be inlined (-XX:MaxInlineSize)
and therefore a subject of further reordering.