SlideShare une entreprise Scribd logo
1  sur  104
Télécharger pour lire hors ligne
Semantics of final fields in java 
Vladimir Sitnikov, Valentin Kovalenko 
sitnikov@netcracker.com, @VladimirSitnikv 
NetCracker 
September 2014
Introduction 
Examples 
2 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Why final is required in 
JMM? 
3 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String safety 
String s = ... 
if ( checkAccess (s)) { 
return readFile (s); 
} 
Is this a valid security check? 
4 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String unsafety in 1.4 
String s = ... 
if ( checkAccess (s)) { 
return readFile (s); 
} 
The answer depends on the java version, and in java 1.4 the code is 
insecure 
5 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String unsafety in 1.4 
String s = GLOBAL ; 
if ( checkAccess (s)) { 
return readFile (s); 
} 
HackThread 
GLOBAL = 
"/tmp/ etc / passwd " 
. substring (4); 
For instance: HackThread executes .substring(4) and transfers it 
via data race to the checker thread 
6 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String unsafety in 1.4 
String s = GLOBAL ; 
if ( checkAccess (s)) { 
return readFile (s); 
} 
HackThread 
GLOBAL = 
"/tmp/ etc / passwd " 
. substring (4); 
In java 1.4 result of substring references the same char array, and 
the value depends on String#offset and String#size 
7 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String unsafety in 1.4 
String s = GLOBAL ; 
if ( checkAccess (s)) { 
return readFile (s); 
} 
HackThread 
GLOBAL = 
"/tmp/ etc / passwd " 
. substring (4); 
race 
race 
Since no synchronization is in place, reader might observe 
not-fully-initialized String 
8 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String unsafety in 1.4 
String s = GLOBAL ; 
if ( checkAccess (s)) { 
return readFile (s); 
} 
HackThread 
GLOBAL = 
"/tmp/ etc / passwd " 
. substring (4); 
race 
race 
checkAccess might observe "/tmp/etc/passwd", and even then 
readFile might observe "/etc/passwd" 
9 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String unsafety in 1.4 
String s = GLOBAL ; 
if ( checkAccess (s)) { 
return readFile (s); 
} 
HackThread 
GLOBAL = 
"/tmp/ etc / passwd " 
. substring (4); 
race 
race 
checkAccess might observe "/tmp/etc/passwd", and even then 
readFile might observe "/etc/passwd" 
Even synchronization on s and volatile will not help! 
10 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
String safety in java 1.5+ 
String s = GLOBAL ; 
if ( checkAccess (s)) { 
return readFile (s); 
} 
HackThread 
GLOBAL = 
"/tmp/ etc / passwd " 
. substring (4); 
hb 
hb 
In java 1.5+ final protects from such non-initialized objects from 
HackThread 
11 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Çà÷åì íàì JMM? 
12 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Quiz 
int x = 1; 
public int neverTryThisAtHome () { 
int i = this .x; // it is 1, isn ’t it? 
this . setX (2); // just updates x to 2 
return this .x - i; // 2 - 1 == ...? 
} 
What is the result? 1? 0? -1? 
13 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Quiz 
int x = 1; 
public int neverTryThisAtHome () { 
int i = this .x; // it is 1, isn ’t it? 
this . setX (2); // just updates x to 2 
return this .x - i; // 2 - 1 == ...? 
} 
OK, the result is 1 
14 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Quiz 
final int x = 1; 
public int neverTryThisAtHome () { 
int i = this .x; // it is 1, isn ’t it? 
this . setX (2); // just updates x to 2 
return this .x - i; // 2 - 1 == ...? 
} 
Let’s add some final 
15 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Quiz 
final int x = 1; 
public int neverTryThisAtHome () { 
int i = this .x; // it is 1, isn ’t it? 
this . setX (2); // just updates x to 2 
return this .x - i; // 2 - 1 == ...? 
} 
The specification allows all the cases: 1, 0, and even -1! (see also 
example 17.5.3-1) 
16 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
A bit of theory 
17 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Program order 
I Program order is a total order among inter-thread actions of 
each thread in source code order 
18 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Program order 
I Program order is a total order among inter-thread actions of 
each thread in source code order 
I Compiler is forbidden to reorder/alter/ignore operations if 
observable behavior violates program order 
19 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Program order 
I Program order is a total order among inter-thread actions of 
each thread in source code order 
I Compiler is forbidden to reorder/alter/ignore operations if 
observable behavior violates program order 
I It does not mean the program is executed in program order 
20 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Program order 
I Program order is a total order among inter-thread actions of 
each thread in source code order 
I Compiler is forbidden to reorder/alter/ignore operations if 
observable behavior violates program order 
I It does not mean the program is executed in program order 
I For instance: program order is not defined for operations on 
local variables 
21 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Partial order 
I In section 17 JLS "partial order" is mentioned 8 times 
22 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Partial order 
I In section 17 JLS "partial order" is mentioned 8 times 
I Partial order is hb 
! a binary relation that is: 
23 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Partial order 
I In section 17 JLS partial order is mentioned 8 times 
I Partial order is hb 
! a binary relation that is: 
I Reflexive: for each element x, x 
hb 
! x 
24 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Partial order 
I In section 17 JLS partial order is mentioned 8 times 
I Partial order is hb 
! a binary relation that is: 
I Reflexive: for each element x, x 
hb 
! x 
I Antisymmetric: if x 
hb 
! y and y 
hb 
! x, then x and y are the same 
element 
25 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Partial order 
I In section 17 JLS partial order is mentioned 8 times 
I Partial order is hb 
! a binary relation that is: 
I Reflexive: for each element x, x 
hb 
! x 
I Antisymmetric: if x 
hb 
! y and y 
hb 
! x, then x and y are the same 
element 
I Transitive: if x 
hb 
! y and y 
hb 
! z, then x 
hb 
! z 
26 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Happens-before 
I General idea of JMM: let’s consider all the executions and forbid 
bad ones 
27 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Happens-before 
I General idea of JMM: let’s consider all the executions and forbid 
bad ones 
I Happens-before is a partial order that selects allowable reads 
28 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Happens-before 
I General idea of JMM: let’s consider all the executions and forbid 
bad ones 
I Happens-before is a partial order that selects allowable reads 
I A read either sees the latest write (in hb order) 
29 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Happens-before 
I General idea of JMM: let’s consider all the executions and forbid 
bad ones 
I Happens-before is a partial order that selects allowable reads 
I A read either sees the latest write (in hb order) 
I Or any write via data race when multiple writes are 
hb -unordered with the read 
30 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Happens-before 
I General idea of JMM: let’s consider all the executions and forbid 
bad ones 
I Happens-before is a partial order that selects allowable reads 
I A read either sees the latest write (in hb order) 
I Or any write via data race when multiple writes are 
hb -unordered with the read 
I It must still obey other rules, especially: 17.4.8 executions and 
causality requirements 
31 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Semantics of final fields 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
I w and r2 – the read and the write in question 
32 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Semantics of final fields 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
I w and r2 – the read and the write in question 
I f – freeze of a final field, that is read in r1 
33 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Semantics of final fields 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
I If the only path from write to read follows all this arrows, then 
we must not see earlier writes 
34 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Semantics of final fields 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
I If the only path from write to read follows all this arrows, then 
we must not see earlier writes 
I If multiple paths exist, you need to go deeper 
35 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Semantics of final fields 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
I If the only path from write to read follows all this arrows, then 
we must not see earlier writes 
I If multiple paths exist, you need to go deeper 
I We use hb notation to distinguish it from hb and since this 
happens-before ordering does not transitively close with other 
happens-before orderings 36 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Freeze action w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
37 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Freeze action w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Freeze action 
38 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Freeze action w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Freeze action 
Field 
Freezes of a final field occur both at the end of the constructor, and 
immediately after each modification 
39 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T local = GLOBAL ; r1 
int localX = local .x; r2 
I r2 reads a field of an object 
40 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T local = GLOBAL ; r1 
int localX = local .x; r2 
I r2 reads a field of an object 
I Current thread did not create the object 
41 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T local = GLOBAL ; r1 
int localX = local .x; r2 
I r2 reads a field of an object 
I Current thread did not create the object 
I Hence, we must read an address of the object somewhere 
42 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T local = GLOBAL ; r1 
int localX = local .x; r2 
dr 
I r2 reads a field of an object 
I Current thread did not create the object 
I Hence, we must read an address of the object somewhere 
I This is called r1 dr 
! r2 
43 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain in two threads w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T localA = new T(); 
GLOBAL = localA ; 
Thread 2 
T localB = GLOBAL ; r1 
if ( localB != null ) { 
int localX = localB .x; r2 
} 
dr 
r1 dr 
! r2 (thread 2 reads a field of object created in a foreign thread) 
44 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain in two threads w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T localA = new T(); a 
GLOBAL = localA ; 
Thread 2 
T localB = GLOBAL ; r1 
if ( localB != null ) { 
int localX = localB .x; r2 
} 
dr 
dr? 
Is there a dr 
! r2? 
45 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain in two threads w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T localA = new T(); a 
GLOBAL = localA ; 
Thread 2 
T localB = GLOBAL ; r1 
if ( localB != null ) { 
int localX = localB .x; r2 
} 
dr 
dr? 
dr does not appear between actions of different threads! 
46 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain: double-check w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T local = GLOBAL ; ra 
local = GLOBAL ; rb 
int localX = local .x; r2 
Is there a dr ? 
47 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Dereference chain: double-check w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T local = GLOBAL ; ra 
local = GLOBAL ; rb 
int localX = local .x; r2 
dr? 
dr? 
One of ra dr 
! r2 or rb dr 
! r2 must exist, however no one can tell 
which one 
48 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Memory chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T o = new T (); 
GL = o; w1 
Thread 2 
T o = GL; r1 
GL2 = o; 
Thread 3 
T o = GL2; 
int r = o.x; 
mc 
If a read sees write, then w1 mc 
! r1 
49 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Memory chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T o = new T (); 
GL = o; w1 
Thread 2 
T o = GL; r1 
GL2 = o; w2 
Thread 3 
T o = GL2; 
int r = o.x; 
mc 
mc 
If a thread writes the address of an object that was initialized in 
another thread, then r1 mc 
! w2 
50 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Memory chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T o = new T (); 
GL = o; w1 
Thread 2 
T o = GL; r1 
GL2 = o; w2 
Thread 3 
T o = GL2; r3 
int r = o.x; 
mc 
mc 
mc 
r3 sees w2 ) w2 mc 
! r3 
51 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Memory chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T o = new T (); 
GL = o; w1 
Thread 2 
T o = GL; r1 
GL2 = o; w2 
Thread 3 
T o = GL2; r3 
int r = o.x; r4 
mc 
mc 
mc dr 
r3 dr 
! r4 (read of a object’s field) 
52 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Memory chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T o = new T (); 
GL = o; w1 
Thread 2 
T o = GL; r1 
GL2 = o; w2 
Thread 3 
T o = GL2; r3 
int r = o.x; r4 
mc 
mc 
mc dr 
mc 
r3 dr 
! r4 (read of a object’s field) ) r3 mc 
! r4 
53 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Memory chain: what is that? w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T o = new T (); 
GL = o; w1 
Thread 2 
T o = GL; r1 
GL2 = o; w2 
Thread 3 
T o = GL2; r3 
int r = o.x; r4 
mc 
mc 
mc dr 
mc 
mc 
mc is transitive (it is a partial order) ) w1 mc 
! r4 
54 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Introduction 
Examples 
55 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Disclaimer 
I All the examples contain data races (why bother otherwise?) 
56 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Disclaimer 
I All the examples contain data races (why bother otherwise?) 
I We do not consider cases when null is observed (those cases are 
not interesting) 
57 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Disclaimer 
I All the examples contain data races (why bother otherwise?) 
I We do not consider cases when null is observed (those cases are 
not interesting) 
I Lots of brains were hurt when preparing the slides 
58 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; 
GLOBAL = l; 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r2 
} 
Can result become 0? 
59 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; 
} 
hb 
hb 
Actions in a thread form happens-before: 
w hb 
! f , f hb 
! a 
60 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; r0 
if (o != null ) { 
int result = o.fx; 
} 
hb 
hb 
mc 
r0 sees write a : 
a mc 
! r0 
61 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; r0 
if (o != null ) { 
int result = o.fx; r1 
} 
hb 
hb 
mc 
dr 
Thread 2 did not create the object, r1 reads its field, and r is the 
only read of the address, thus we have dereference chain: 
r0 dr 
! r1 
62 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; r0 
if (o != null ) { 
int result = o.fx; r1 
} 
hb 
hb 
mc 
dr 
mc 
r0 dr 
! r1 ) r0 mc 
! r1 
63 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; r0 
if (o != null ) { 
int result = o.fx; r1 
} 
hb 
hb 
mc 
mc 
mc 
a mc 
! r1 ( mc is transitive) 
64 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r1 r2 
} 
hb 
hb 
mc 
dr 
Let’s pick r2 = r 1, then r1 dr 
! r2 ( dr is reflexive) 
65 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r1 r2 
} 
hb 
hb 
mc 
dr 
hb* 
Here all the requirements for HB: 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
66 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Trivial final (1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
}}; f 
GLOBAL = l; a 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r1 r2 
} 
hb 
hb 
mc 
dr 
hb* 
(w hb 
! r2) ) result 2 f42g 
67 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array in a final field (2) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
u [0] = 42; w 
fx = u; 
}}; 
GLOBAL = l; 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; 
int result = lfx [0]; r2 
} 
Can result become 0? 
68 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array in a final field (2) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
u [0] = 42; w 
fx = u; 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; 
int result = lfx [0]; r2 
} 
hb 
hb 
Actions in a thread form happens-before: 
w hb 
! f , f hb 
! a 
69 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array in a final field (2) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
u [0] = 42; w 
fx = u; 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; r1 
int result = lfx [0]; r2 
} 
hb 
hb 
mc 
r1 sees write a (it reads a regular final field): 
a mc 
! r1 
70 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array in a final field (2) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
u [0] = 42; w 
fx = u; 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; r1 
int result = lfx [0]; r2 
} 
hb 
hb 
mc 
dr 
Thread 2 did not create array, r2 reads an element of the array, r1 is 
the only read of the address of the array, thus dereference chain: 
r1 dr 
! r2 
71 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array in a final field (2) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
u [0] = 42; w 
fx = u; 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; r1 
int result = lfx [0]; r2 
} 
hb 
hb 
mc 
dr 
hb* 
Here are all the requirements for HB: 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
72 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array in a final field (2) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
u [0] = 42; w 
fx = u; 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; r1 
int result = lfx [0]; r2 
} 
hb 
hb 
mc 
dr 
hb* 
(w hb 
! r2) ) result 2 f42g 
73 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array reversed (2.1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
fx = u; // (!) 
u [0] = 42; w 
}}; 
GLOBAL = l; 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; 
int result = lfx [0]; 
} 
Can result become 0? 
74 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array reversed (2.1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
fx = u; // (!) 
u [0] = 42; w 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; r1 
int result = lfx [0]; r2 
} 
hb 
hb 
mc 
dr 
hb 
We compose hb exactly as in the previous example 
75 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Array reversed (2.1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T l = new T() {{ 
int [] u = new int [1]; 
fx = u; // (!) 
u [0] = 42; w 
}}; f 
GLOBAL = l; a 
T o = GLOBAL ; 
if (o != null ) { 
int [] lfx = o.fx; r1 
int result = lfx [0]; r2 
} 
hb 
hb 
mc 
dr 
hb 
(w hb 
! r2) ) result 2 f42g 
The result does not depend on the order of assignment to final fields! 
76 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
this leaks (3) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLOBAL = this ; 
}}; 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r2 
} 
Can result become 0? 
77 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
this leaks (3) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLOBAL = this ; a 
}}; f 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r2 
} 
hb 
hb 
Actions in thread form happens-before: 
w hb 
! f , a hb 
! f 
78 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
this leaks (3) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLOBAL = this ; a 
}}; f 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r2 
} 
hb 
hb? 
hb 
For hb we need f hb 
! a! 
79 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
this leaks (3) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLOBAL = this ; a 
}}; f 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r2 
} 
hb 
hb? 
hb 
If a hb 
! f and f hb 
! a, thus a = f (anti-symmetry of hb ) 
However a is cannot be a freeze action! 
80 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
this leaks (3) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLOBAL = this ; a 
}}; f 
Thread 2 
T o = GLOBAL ; 
if (o != null ) { 
int result = o.fx; r2 
} 
hb 
hb? 
hb 
There is no hb , thus all the cases are possible: result 2 f0; 42g 
81 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Unintentional this leak (4) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLb = this ; 
}}; 
GLa = l; 
Thread 2 
T u = GLb; 
T o = GLa; 
if (o != null ) { 
int result = o.fx; r2 
} 
Can result become 0? 
82 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Unintentional this leak (4) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLb = this ; b 
}}; f 
GLa = l; a 
Thread 2 
T u = GLb; 
T o = GLa; 
if (o != null ) { 
int result = o.fx; 
} 
hb 
hb 
hb? 
Actions in a thread form happens-before: 
w hb 
! f , f hb 
! a 
83 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Unintentional this leak (4) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLb = this ; b 
}}; f 
GLa = l; a 
Thread 2 
T u = GLb; 
T o = GLa; ra 
if (o != null ) { 
int result = o.fx; 
} 
hb 
hb 
hb? 
mc 
Suppose thread 2 sees GLa, thus a mc 
! ra! 
84 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Unintentional this leak (4) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLb = this ; b 
}}; f 
GLa = l; a 
Thread 2 
T u = GLb; rb 
T o = GLa; ra 
if (o != null ) { 
int result = o.fx; r1 
} 
hb 
hb 
hb? 
mc 
dr? 
dr? 
There should be dr somewhere: rb dr 
! r1 or ra dr 
! r1 
85 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Unintentional this leak (4) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLb = this ; b 
}}; f 
GLa = l; a 
Thread 2 
T u = GLb; rb 
T o = GLa; ra 
if (o != null ) { 
int result = o.fx; r1 
} 
hb 
hb 
hb? 
mc 
dr? 
dr 
! r 1, then we fail, since w hb 
If rb dr 
! r1 can not be completed 
86 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Unintentional this leak (4) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
T l = new T() {{ 
fx = 42; w 
GLb = this ; b 
}}; f 
GLa = l; a 
Thread 2 
T u = GLb; rb 
T o = GLa; ra 
if (o != null ) { 
int result = o.fx; r1 
} 
hb 
hb 
hb? 
mc 
dr? 
dr 
Conclusion: if a thread had ever seen object with unfrozen fields, 
then there is no final semantics for that object! 
87 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Reflection in action (5) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; w1 
}}; 
GLOBAL = t; 
U w = new U (); 
w.x = 42; w2 
reflectSet (t.fu , w); 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; r2 
} 
Can result become 0? 
88 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Reflection in action (5) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; 
}}; 
GLOBAL = t; 
U w = new U (); 
w.x = 42; w2 
reflectSet (t.fu , w); 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; r2 
} 
hb*? 
We’d better have w2 hb 
! r2 (otherwise we must not see the write 
of 0 in w.x) 
89 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Reflection in action (5) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; 
}}; 
GLOBAL = t; 
U w = new U (); 
w.x = 42; w2 
reflectSet (t.fu , w); f2 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; r2 
} 
hb*? 
f2 does not work for hb : there is no suitable f 2 hb 
! a 
90 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Reflection in action (5) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; 
}}; f1 
GLOBAL = t; 
U w = new U (); 
w.x = 42; w2 
reflectSet (t.fu , w); f2 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; r2 
} 
hb*? 
hb? 
f1 does not work for hb as well: it must be w2 hb 
! f 1 
91 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Reflection in action (5) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; 
}}; f1 
GLOBAL = t; 
U w = new U (); 
w.x = 42; w2 
reflectSet (t.fu , w); f2 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; r2 
} 
hb*? 
hb? 
It turns out r2 is not denied to observe 0 
92 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Reflection in action (5) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; 
}}; f1 
GLOBAL = t; a 
U w = new U(); 
w.x = 42; w2 
reflectSet (t.fu , w); f2 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; r2 
} 
hb*? 
hb? 
Conclusion: do not alter the final field after you publish its contents 
result 2 f0; 1; 42g 
93 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Let’s fix reflection (5.1) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
T t = new T() {{ 
fu = new U (); 
fu.x = 1; 
}}; 
U w = new U (); 
w.x = 42; 
reflectSet (t.fu , w); 
GLOBAL = t; a 
Thread 2 
T t = GLOBAL ; 
if (t != null ) { 
U u = t.fu; 
int result = u.x; 
} 
If we publish the object after all modifications of final fields, the 
publication is safe: result 2 f1; 42g 
94 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; 
GL = a; 
Thread 2 
A a = GL; 
B = new B() {{ 
fb = o; 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
A a = b.fb; 
int r = a.fx; r2 
Can result become 0? 
95 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
mc 
A a = b.fb; rb 
int r = a.fx; r1 
mc 
rb sees wb ) wb mc 
! rb 
ra sees wa : wa mc 
! ra 
96 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
mc 
A a = b.fb; rb 
int r = a.fx; r1 
mc 
mc 
Thread 2 writes an address of a foreign-created object, thus 
ra mc 
! wb 
97 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
mc 
A a = b.fb; rb 
int r = a.fx; r1 
mc 
mc 
dr 
Therad 3 did not create object A, r reads its field, and rb is the 
only read of A’s address, thus dereference chain: 
rb dr 
! r1 
98 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
mc 
A a = b.fb; rb 
int r = a.fx; r1 
mc 
mc 
dr 
mc 
rb dr 
! r1 ) rb mc 
! r1 
99 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
mc 
A a = b.fb; rb 
int r = a.fx; r1 
mc 
mc 
mc 
mc 
mc is transitive (since it is a partial order) ) wa mc 
! r1 
100 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; f 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
A a = b.fb; rb 
int r = a.fx; r1 r2 
mc 
dr 
Let’s pick r2 = r 1, thus r1 dr 
! r2 ( dr is reflexive) 
101 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; f 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
A a = b.fb; rb 
int r = a.fx; r1 r2 
mc 
dr 
hb 
hb 
hb* 
Here are all the requirements for HB: 
w hb 
! f hb 
! a mc 
! r2 ) w hb 
! r1 dr 
! r2 
102 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Final wrapper (6) w hb 
! f hb 
! a mc 
! r1 dr 
! r2 
Thread 1 
A a = new O() {{ 
fx = 42; w 
}}; f 
GL = a; wa 
Thread 2 
A a = GL; ra 
B = new B() {{ 
fb = o; wb 
}}; 
GL2 = b; 
Thread 3 
B B = GL2; 
A a = b.fb; rb 
int r = a.fx; r1 r2 
mc 
dr 
hb 
hb 
hb* 
(w hb 
! r2) ) result 2 f42g 
103 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
Questions? 
104 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Contenu connexe

Tendances

O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本Takahiro YAMADA
 
Elasticsearch as a Distributed System
Elasticsearch as a Distributed SystemElasticsearch as a Distributed System
Elasticsearch as a Distributed SystemSatoyuki Tsukano
 
コンテナ環境でJavaイメージを小さくする方法!
コンテナ環境でJavaイメージを小さくする方法!コンテナ環境でJavaイメージを小さくする方法!
コンテナ環境でJavaイメージを小さくする方法!オラクルエンジニア通信
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48Preferred Networks
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersSeiya Mizuno
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM LoggingYuji Kubota
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
java.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷javajava.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷javaYuji Kubota
 
分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーションMasahito Zembutsu
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方Recruit Lifestyle Co., Ltd.
 
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)NTT DATA Technology & Innovation
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVMJeroen Reijn
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
【メモ】一般的に設計書に定義される項目例
【メモ】一般的に設計書に定義される項目例【メモ】一般的に設計書に定義される項目例
【メモ】一般的に設計書に定義される項目例Hirokazu Yatsunami
 
PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会
PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会
PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会Shigeru Hanada
 
ゲーム開発を知らない人にも分かるKLabのゲーム開発運営
ゲーム開発を知らない人にも分かるKLabのゲーム開発運営ゲーム開発を知らない人にも分かるKLabのゲーム開発運営
ゲーム開発を知らない人にも分かるKLabのゲーム開発運営KLab Inc. / Tech
 
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)NTT DATA Technology & Innovation
 
『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!
『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!
『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!株式会社クライム
 

Tendances (20)

O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
 
Elasticsearch as a Distributed System
Elasticsearch as a Distributed SystemElasticsearch as a Distributed System
Elasticsearch as a Distributed System
 
コンテナ環境でJavaイメージを小さくする方法!
コンテナ環境でJavaイメージを小さくする方法!コンテナ環境でJavaイメージを小さくする方法!
コンテナ環境でJavaイメージを小さくする方法!
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM Logging
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
java.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷javajava.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷java
 
分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション分散環境におけるDocker とオーケストレーション
分散環境におけるDocker とオーケストレーション
 
分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方分散トレーシングAWS:X-Rayとの上手い付き合い方
分散トレーシングAWS:X-Rayとの上手い付き合い方
 
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
BigtopでHadoopをビルドする(Open Source Conference 2021 Online/Spring 発表資料)
 
Shootout! Template engines for the JVM
Shootout! Template engines for the JVMShootout! Template engines for the JVM
Shootout! Template engines for the JVM
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
【メモ】一般的に設計書に定義される項目例
【メモ】一般的に設計書に定義される項目例【メモ】一般的に設計書に定義される項目例
【メモ】一般的に設計書に定義される項目例
 
PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会
PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会
PostgreSQLのパラレル化に向けた取り組み@第30回(仮名)PostgreSQL勉強会
 
ゲーム開発を知らない人にも分かるKLabのゲーム開発運営
ゲーム開発を知らない人にも分かるKLabのゲーム開発運営ゲーム開発を知らない人にも分かるKLabのゲーム開発運営
ゲーム開発を知らない人にも分かるKLabのゲーム開発運営
 
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
 
噛み砕いてKafka Streams #kafkajp
噛み砕いてKafka Streams #kafkajp噛み砕いてKafka Streams #kafkajp
噛み砕いてKafka Streams #kafkajp
 
『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!
『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!
『データベースのどこが問題?』を時間かけずにレスポンス・タイム分析(RTA)!
 

En vedette

Семантика final полей в java
Семантика final полей в javaСемантика final полей в java
Семантика final полей в javaVladimir Sitnikov
 
Трудовые будни инженера производительности
Трудовые будни инженера производительностиТрудовые будни инженера производительности
Трудовые будни инженера производительностиVladimir Sitnikov
 
High Performance Jdbc
High Performance JdbcHigh Performance Jdbc
High Performance JdbcSam Pattsin
 
A step-by-step approach toward high quality OutOfMemoryError analysis
A step-by-step approach toward high quality OutOfMemoryError analysisA step-by-step approach toward high quality OutOfMemoryError analysis
A step-by-step approach toward high quality OutOfMemoryError analysisVladimir Sitnikov
 
Implement your own profiler with blackjack and fun
Implement your own profiler with blackjack and funImplement your own profiler with blackjack and fun
Implement your own profiler with blackjack and funVladimir Sitnikov
 
PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performanceVladimir Sitnikov
 
Проблемы производительности open source библиотек
Проблемы производительности open source библиотекПроблемы производительности open source библиотек
Проблемы производительности open source библиотекVladimir Sitnikov
 
PostgreSQL и JDBC: выжимаем все соки
PostgreSQL и JDBC: выжимаем все сокиPostgreSQL и JDBC: выжимаем все соки
PostgreSQL и JDBC: выжимаем все сокиVladimir Sitnikov
 
Developing PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsDeveloping PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsFuenteovejuna
 
Подводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестированииПодводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестированииVladimir Sitnikov
 
SIGGRAPH Asia 2008 Modern OpenGL
SIGGRAPH Asia 2008 Modern OpenGLSIGGRAPH Asia 2008 Modern OpenGL
SIGGRAPH Asia 2008 Modern OpenGLMark Kilgard
 
Linux BPF Superpowers
Linux BPF SuperpowersLinux BPF Superpowers
Linux BPF SuperpowersBrendan Gregg
 
Linux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsLinux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsBrendan Gregg
 
Linux Systems Performance 2016
Linux Systems Performance 2016Linux Systems Performance 2016
Linux Systems Performance 2016Brendan Gregg
 
Broken Linux Performance Tools 2016
Broken Linux Performance Tools 2016Broken Linux Performance Tools 2016
Broken Linux Performance Tools 2016Brendan Gregg
 
BPF: Tracing and more
BPF: Tracing and moreBPF: Tracing and more
BPF: Tracing and moreBrendan Gregg
 
Velocity 2015 linux perf tools
Velocity 2015 linux perf toolsVelocity 2015 linux perf tools
Velocity 2015 linux perf toolsBrendan Gregg
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at NetflixBrendan Gregg
 

En vedette (18)

Семантика final полей в java
Семантика final полей в javaСемантика final полей в java
Семантика final полей в java
 
Трудовые будни инженера производительности
Трудовые будни инженера производительностиТрудовые будни инженера производительности
Трудовые будни инженера производительности
 
High Performance Jdbc
High Performance JdbcHigh Performance Jdbc
High Performance Jdbc
 
A step-by-step approach toward high quality OutOfMemoryError analysis
A step-by-step approach toward high quality OutOfMemoryError analysisA step-by-step approach toward high quality OutOfMemoryError analysis
A step-by-step approach toward high quality OutOfMemoryError analysis
 
Implement your own profiler with blackjack and fun
Implement your own profiler with blackjack and funImplement your own profiler with blackjack and fun
Implement your own profiler with blackjack and fun
 
PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performance
 
Проблемы производительности open source библиотек
Проблемы производительности open source библиотекПроблемы производительности open source библиотек
Проблемы производительности open source библиотек
 
PostgreSQL и JDBC: выжимаем все соки
PostgreSQL и JDBC: выжимаем все сокиPostgreSQL и JDBC: выжимаем все соки
PostgreSQL и JDBC: выжимаем все соки
 
Developing PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsDeveloping PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon Riggs
 
Подводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестированииПодводные камни в нагрузочном тестировании
Подводные камни в нагрузочном тестировании
 
SIGGRAPH Asia 2008 Modern OpenGL
SIGGRAPH Asia 2008 Modern OpenGLSIGGRAPH Asia 2008 Modern OpenGL
SIGGRAPH Asia 2008 Modern OpenGL
 
Linux BPF Superpowers
Linux BPF SuperpowersLinux BPF Superpowers
Linux BPF Superpowers
 
Linux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old SecretsLinux Performance Analysis: New Tools and Old Secrets
Linux Performance Analysis: New Tools and Old Secrets
 
Linux Systems Performance 2016
Linux Systems Performance 2016Linux Systems Performance 2016
Linux Systems Performance 2016
 
Broken Linux Performance Tools 2016
Broken Linux Performance Tools 2016Broken Linux Performance Tools 2016
Broken Linux Performance Tools 2016
 
BPF: Tracing and more
BPF: Tracing and moreBPF: Tracing and more
BPF: Tracing and more
 
Velocity 2015 linux perf tools
Velocity 2015 linux perf toolsVelocity 2015 linux perf tools
Velocity 2015 linux perf tools
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at Netflix
 

Similaire à Final field semantics

Critical software developement
Critical software developementCritical software developement
Critical software developementnedseb
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial javaTpoint s
 
Introduction to Operating Systems - Part3
Introduction to Operating Systems - Part3Introduction to Operating Systems - Part3
Introduction to Operating Systems - Part3Amir Payberah
 
C Programming Language Tutorial for beginners - JavaTpoint
C Programming Language Tutorial for beginners - JavaTpointC Programming Language Tutorial for beginners - JavaTpoint
C Programming Language Tutorial for beginners - JavaTpointJavaTpoint.Com
 
From Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPFrom Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPAlbert Chen
 
Java 8 - Lambdas and much more
Java 8 - Lambdas and much moreJava 8 - Lambdas and much more
Java 8 - Lambdas and much moreAlin Pandichi
 
Complete c programming presentation
Complete c programming presentationComplete c programming presentation
Complete c programming presentationnadim akber
 
Ceh v5 module 20 buffer overflow
Ceh v5 module 20 buffer overflowCeh v5 module 20 buffer overflow
Ceh v5 module 20 buffer overflowVi Tính Hoàng Nam
 
Java fx smart code econ
Java fx smart code econJava fx smart code econ
Java fx smart code econTom Schindl
 
Lambdas And Streams Hands On Lab
Lambdas And Streams Hands On LabLambdas And Streams Hands On Lab
Lambdas And Streams Hands On LabSimon Ritter
 
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...apidays
 
The best unix shell scripting interview questions 2018 learn now!
The best unix shell scripting interview questions 2018   learn now!The best unix shell scripting interview questions 2018   learn now!
The best unix shell scripting interview questions 2018 learn now!mia avery
 
Lambdas Hands On Lab
Lambdas Hands On LabLambdas Hands On Lab
Lambdas Hands On LabSimon Ritter
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbaivibrantuser
 
Go Native : Squeeze the juice out of your 64-bit processor using C++
Go Native : Squeeze the juice out of your 64-bit processor using C++Go Native : Squeeze the juice out of your 64-bit processor using C++
Go Native : Squeeze the juice out of your 64-bit processor using C++Fernando Moreira
 
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...AdaCore
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil Witecki
 

Similaire à Final field semantics (20)

Critical software developement
Critical software developementCritical software developement
Critical software developement
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
Introduction to Operating Systems - Part3
Introduction to Operating Systems - Part3Introduction to Operating Systems - Part3
Introduction to Operating Systems - Part3
 
C Programming Language Tutorial for beginners - JavaTpoint
C Programming Language Tutorial for beginners - JavaTpointC Programming Language Tutorial for beginners - JavaTpoint
C Programming Language Tutorial for beginners - JavaTpoint
 
From Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPFrom Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHP
 
Java 8 - Lambdas and much more
Java 8 - Lambdas and much moreJava 8 - Lambdas and much more
Java 8 - Lambdas and much more
 
Complete c programming presentation
Complete c programming presentationComplete c programming presentation
Complete c programming presentation
 
Ceh v5 module 20 buffer overflow
Ceh v5 module 20 buffer overflowCeh v5 module 20 buffer overflow
Ceh v5 module 20 buffer overflow
 
Java fx smart code econ
Java fx smart code econJava fx smart code econ
Java fx smart code econ
 
Lambdas And Streams Hands On Lab
Lambdas And Streams Hands On LabLambdas And Streams Hands On Lab
Lambdas And Streams Hands On Lab
 
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
 
The best unix shell scripting interview questions 2018 learn now!
The best unix shell scripting interview questions 2018   learn now!The best unix shell scripting interview questions 2018   learn now!
The best unix shell scripting interview questions 2018 learn now!
 
Tom Kyte at Hotsos 2015
Tom Kyte at Hotsos 2015Tom Kyte at Hotsos 2015
Tom Kyte at Hotsos 2015
 
Lambdas Hands On Lab
Lambdas Hands On LabLambdas Hands On Lab
Lambdas Hands On Lab
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
The Veil-Framework
The Veil-FrameworkThe Veil-Framework
The Veil-Framework
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbai
 
Go Native : Squeeze the juice out of your 64-bit processor using C++
Go Native : Squeeze the juice out of your 64-bit processor using C++Go Native : Squeeze the juice out of your 64-bit processor using C++
Go Native : Squeeze the juice out of your 64-bit processor using C++
 
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
GNAT Pro User Day: Ada 2012, Ravenscar and SPARK running on an Atmel ARM M4 (...
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, code
 

Final field semantics

  • 1. Semantics of final fields in java Vladimir Sitnikov, Valentin Kovalenko sitnikov@netcracker.com, @VladimirSitnikv NetCracker September 2014
  • 2. Introduction Examples 2 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 3. Why final is required in JMM? 3 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 4. String safety String s = ... if ( checkAccess (s)) { return readFile (s); } Is this a valid security check? 4 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 5. String unsafety in 1.4 String s = ... if ( checkAccess (s)) { return readFile (s); } The answer depends on the java version, and in java 1.4 the code is insecure 5 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 6. String unsafety in 1.4 String s = GLOBAL ; if ( checkAccess (s)) { return readFile (s); } HackThread GLOBAL = "/tmp/ etc / passwd " . substring (4); For instance: HackThread executes .substring(4) and transfers it via data race to the checker thread 6 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 7. String unsafety in 1.4 String s = GLOBAL ; if ( checkAccess (s)) { return readFile (s); } HackThread GLOBAL = "/tmp/ etc / passwd " . substring (4); In java 1.4 result of substring references the same char array, and the value depends on String#offset and String#size 7 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 8. String unsafety in 1.4 String s = GLOBAL ; if ( checkAccess (s)) { return readFile (s); } HackThread GLOBAL = "/tmp/ etc / passwd " . substring (4); race race Since no synchronization is in place, reader might observe not-fully-initialized String 8 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 9. String unsafety in 1.4 String s = GLOBAL ; if ( checkAccess (s)) { return readFile (s); } HackThread GLOBAL = "/tmp/ etc / passwd " . substring (4); race race checkAccess might observe "/tmp/etc/passwd", and even then readFile might observe "/etc/passwd" 9 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 10. String unsafety in 1.4 String s = GLOBAL ; if ( checkAccess (s)) { return readFile (s); } HackThread GLOBAL = "/tmp/ etc / passwd " . substring (4); race race checkAccess might observe "/tmp/etc/passwd", and even then readFile might observe "/etc/passwd" Even synchronization on s and volatile will not help! 10 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 11. String safety in java 1.5+ String s = GLOBAL ; if ( checkAccess (s)) { return readFile (s); } HackThread GLOBAL = "/tmp/ etc / passwd " . substring (4); hb hb In java 1.5+ final protects from such non-initialized objects from HackThread 11 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 12. Çà÷åì íàì JMM? 12 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 13. Quiz int x = 1; public int neverTryThisAtHome () { int i = this .x; // it is 1, isn ’t it? this . setX (2); // just updates x to 2 return this .x - i; // 2 - 1 == ...? } What is the result? 1? 0? -1? 13 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 14. Quiz int x = 1; public int neverTryThisAtHome () { int i = this .x; // it is 1, isn ’t it? this . setX (2); // just updates x to 2 return this .x - i; // 2 - 1 == ...? } OK, the result is 1 14 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 15. Quiz final int x = 1; public int neverTryThisAtHome () { int i = this .x; // it is 1, isn ’t it? this . setX (2); // just updates x to 2 return this .x - i; // 2 - 1 == ...? } Let’s add some final 15 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 16. Quiz final int x = 1; public int neverTryThisAtHome () { int i = this .x; // it is 1, isn ’t it? this . setX (2); // just updates x to 2 return this .x - i; // 2 - 1 == ...? } The specification allows all the cases: 1, 0, and even -1! (see also example 17.5.3-1) 16 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 17. A bit of theory 17 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 18. Program order I Program order is a total order among inter-thread actions of each thread in source code order 18 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 19. Program order I Program order is a total order among inter-thread actions of each thread in source code order I Compiler is forbidden to reorder/alter/ignore operations if observable behavior violates program order 19 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 20. Program order I Program order is a total order among inter-thread actions of each thread in source code order I Compiler is forbidden to reorder/alter/ignore operations if observable behavior violates program order I It does not mean the program is executed in program order 20 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 21. Program order I Program order is a total order among inter-thread actions of each thread in source code order I Compiler is forbidden to reorder/alter/ignore operations if observable behavior violates program order I It does not mean the program is executed in program order I For instance: program order is not defined for operations on local variables 21 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 22. Partial order I In section 17 JLS "partial order" is mentioned 8 times 22 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 23. Partial order I In section 17 JLS "partial order" is mentioned 8 times I Partial order is hb ! a binary relation that is: 23 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 24. Partial order I In section 17 JLS partial order is mentioned 8 times I Partial order is hb ! a binary relation that is: I Reflexive: for each element x, x hb ! x 24 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 25. Partial order I In section 17 JLS partial order is mentioned 8 times I Partial order is hb ! a binary relation that is: I Reflexive: for each element x, x hb ! x I Antisymmetric: if x hb ! y and y hb ! x, then x and y are the same element 25 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 26. Partial order I In section 17 JLS partial order is mentioned 8 times I Partial order is hb ! a binary relation that is: I Reflexive: for each element x, x hb ! x I Antisymmetric: if x hb ! y and y hb ! x, then x and y are the same element I Transitive: if x hb ! y and y hb ! z, then x hb ! z 26 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 27. Happens-before I General idea of JMM: let’s consider all the executions and forbid bad ones 27 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 28. Happens-before I General idea of JMM: let’s consider all the executions and forbid bad ones I Happens-before is a partial order that selects allowable reads 28 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 29. Happens-before I General idea of JMM: let’s consider all the executions and forbid bad ones I Happens-before is a partial order that selects allowable reads I A read either sees the latest write (in hb order) 29 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 30. Happens-before I General idea of JMM: let’s consider all the executions and forbid bad ones I Happens-before is a partial order that selects allowable reads I A read either sees the latest write (in hb order) I Or any write via data race when multiple writes are hb -unordered with the read 30 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 31. Happens-before I General idea of JMM: let’s consider all the executions and forbid bad ones I Happens-before is a partial order that selects allowable reads I A read either sees the latest write (in hb order) I Or any write via data race when multiple writes are hb -unordered with the read I It must still obey other rules, especially: 17.4.8 executions and causality requirements 31 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 32. Semantics of final fields w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 I w and r2 – the read and the write in question 32 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 33. Semantics of final fields w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 I w and r2 – the read and the write in question I f – freeze of a final field, that is read in r1 33 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 34. Semantics of final fields w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 I If the only path from write to read follows all this arrows, then we must not see earlier writes 34 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 35. Semantics of final fields w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 I If the only path from write to read follows all this arrows, then we must not see earlier writes I If multiple paths exist, you need to go deeper 35 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 36. Semantics of final fields w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 I If the only path from write to read follows all this arrows, then we must not see earlier writes I If multiple paths exist, you need to go deeper I We use hb notation to distinguish it from hb and since this happens-before ordering does not transitively close with other happens-before orderings 36 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 37. Freeze action w hb ! f hb ! a mc ! r1 dr ! r2 37 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 38. Freeze action w hb ! f hb ! a mc ! r1 dr ! r2 Freeze action 38 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 39. Freeze action w hb ! f hb ! a mc ! r1 dr ! r2 Freeze action Field Freezes of a final field occur both at the end of the constructor, and immediately after each modification 39 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 40. Dereference chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 T local = GLOBAL ; r1 int localX = local .x; r2 I r2 reads a field of an object 40 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 41. Dereference chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 T local = GLOBAL ; r1 int localX = local .x; r2 I r2 reads a field of an object I Current thread did not create the object 41 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 42. Dereference chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 T local = GLOBAL ; r1 int localX = local .x; r2 I r2 reads a field of an object I Current thread did not create the object I Hence, we must read an address of the object somewhere 42 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 43. Dereference chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 T local = GLOBAL ; r1 int localX = local .x; r2 dr I r2 reads a field of an object I Current thread did not create the object I Hence, we must read an address of the object somewhere I This is called r1 dr ! r2 43 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 44. Dereference chain in two threads w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T localA = new T(); GLOBAL = localA ; Thread 2 T localB = GLOBAL ; r1 if ( localB != null ) { int localX = localB .x; r2 } dr r1 dr ! r2 (thread 2 reads a field of object created in a foreign thread) 44 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 45. Dereference chain in two threads w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T localA = new T(); a GLOBAL = localA ; Thread 2 T localB = GLOBAL ; r1 if ( localB != null ) { int localX = localB .x; r2 } dr dr? Is there a dr ! r2? 45 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 46. Dereference chain in two threads w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T localA = new T(); a GLOBAL = localA ; Thread 2 T localB = GLOBAL ; r1 if ( localB != null ) { int localX = localB .x; r2 } dr dr? dr does not appear between actions of different threads! 46 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 47. Dereference chain: double-check w hb ! f hb ! a mc ! r1 dr ! r2 T local = GLOBAL ; ra local = GLOBAL ; rb int localX = local .x; r2 Is there a dr ? 47 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 48. Dereference chain: double-check w hb ! f hb ! a mc ! r1 dr ! r2 T local = GLOBAL ; ra local = GLOBAL ; rb int localX = local .x; r2 dr? dr? One of ra dr ! r2 or rb dr ! r2 must exist, however no one can tell which one 48 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 49. Memory chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T o = new T (); GL = o; w1 Thread 2 T o = GL; r1 GL2 = o; Thread 3 T o = GL2; int r = o.x; mc If a read sees write, then w1 mc ! r1 49 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 50. Memory chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T o = new T (); GL = o; w1 Thread 2 T o = GL; r1 GL2 = o; w2 Thread 3 T o = GL2; int r = o.x; mc mc If a thread writes the address of an object that was initialized in another thread, then r1 mc ! w2 50 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 51. Memory chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T o = new T (); GL = o; w1 Thread 2 T o = GL; r1 GL2 = o; w2 Thread 3 T o = GL2; r3 int r = o.x; mc mc mc r3 sees w2 ) w2 mc ! r3 51 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 52. Memory chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T o = new T (); GL = o; w1 Thread 2 T o = GL; r1 GL2 = o; w2 Thread 3 T o = GL2; r3 int r = o.x; r4 mc mc mc dr r3 dr ! r4 (read of a object’s field) 52 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 53. Memory chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T o = new T (); GL = o; w1 Thread 2 T o = GL; r1 GL2 = o; w2 Thread 3 T o = GL2; r3 int r = o.x; r4 mc mc mc dr mc r3 dr ! r4 (read of a object’s field) ) r3 mc ! r4 53 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 54. Memory chain: what is that? w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T o = new T (); GL = o; w1 Thread 2 T o = GL; r1 GL2 = o; w2 Thread 3 T o = GL2; r3 int r = o.x; r4 mc mc mc dr mc mc mc is transitive (it is a partial order) ) w1 mc ! r4 54 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 55. Introduction Examples 55 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 56. Disclaimer I All the examples contain data races (why bother otherwise?) 56 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 57. Disclaimer I All the examples contain data races (why bother otherwise?) I We do not consider cases when null is observed (those cases are not interesting) 57 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 58. Disclaimer I All the examples contain data races (why bother otherwise?) I We do not consider cases when null is observed (those cases are not interesting) I Lots of brains were hurt when preparing the slides 58 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 59. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; GLOBAL = l; Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r2 } Can result become 0? 59 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 60. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; } hb hb Actions in a thread form happens-before: w hb ! f , f hb ! a 60 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 61. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; r0 if (o != null ) { int result = o.fx; } hb hb mc r0 sees write a : a mc ! r0 61 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 62. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; r0 if (o != null ) { int result = o.fx; r1 } hb hb mc dr Thread 2 did not create the object, r1 reads its field, and r is the only read of the address, thus we have dereference chain: r0 dr ! r1 62 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 63. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; r0 if (o != null ) { int result = o.fx; r1 } hb hb mc dr mc r0 dr ! r1 ) r0 mc ! r1 63 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 64. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; r0 if (o != null ) { int result = o.fx; r1 } hb hb mc mc mc a mc ! r1 ( mc is transitive) 64 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 65. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r1 r2 } hb hb mc dr Let’s pick r2 = r 1, then r1 dr ! r2 ( dr is reflexive) 65 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 66. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r1 r2 } hb hb mc dr hb* Here all the requirements for HB: w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 66 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 67. Trivial final (1) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w }}; f GLOBAL = l; a Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r1 r2 } hb hb mc dr hb* (w hb ! r2) ) result 2 f42g 67 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 68. Array in a final field (2) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; u [0] = 42; w fx = u; }}; GLOBAL = l; T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; int result = lfx [0]; r2 } Can result become 0? 68 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 69. Array in a final field (2) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; u [0] = 42; w fx = u; }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; int result = lfx [0]; r2 } hb hb Actions in a thread form happens-before: w hb ! f , f hb ! a 69 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 70. Array in a final field (2) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; u [0] = 42; w fx = u; }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; r1 int result = lfx [0]; r2 } hb hb mc r1 sees write a (it reads a regular final field): a mc ! r1 70 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 71. Array in a final field (2) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; u [0] = 42; w fx = u; }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; r1 int result = lfx [0]; r2 } hb hb mc dr Thread 2 did not create array, r2 reads an element of the array, r1 is the only read of the address of the array, thus dereference chain: r1 dr ! r2 71 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 72. Array in a final field (2) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; u [0] = 42; w fx = u; }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; r1 int result = lfx [0]; r2 } hb hb mc dr hb* Here are all the requirements for HB: w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 72 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 73. Array in a final field (2) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; u [0] = 42; w fx = u; }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; r1 int result = lfx [0]; r2 } hb hb mc dr hb* (w hb ! r2) ) result 2 f42g 73 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 74. Array reversed (2.1) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; fx = u; // (!) u [0] = 42; w }}; GLOBAL = l; T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; int result = lfx [0]; } Can result become 0? 74 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 75. Array reversed (2.1) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; fx = u; // (!) u [0] = 42; w }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; r1 int result = lfx [0]; r2 } hb hb mc dr hb We compose hb exactly as in the previous example 75 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 76. Array reversed (2.1) w hb ! f hb ! a mc ! r1 dr ! r2 T l = new T() {{ int [] u = new int [1]; fx = u; // (!) u [0] = 42; w }}; f GLOBAL = l; a T o = GLOBAL ; if (o != null ) { int [] lfx = o.fx; r1 int result = lfx [0]; r2 } hb hb mc dr hb (w hb ! r2) ) result 2 f42g The result does not depend on the order of assignment to final fields! 76 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 77. this leaks (3) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLOBAL = this ; }}; Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r2 } Can result become 0? 77 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 78. this leaks (3) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLOBAL = this ; a }}; f Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r2 } hb hb Actions in thread form happens-before: w hb ! f , a hb ! f 78 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 79. this leaks (3) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLOBAL = this ; a }}; f Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r2 } hb hb? hb For hb we need f hb ! a! 79 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 80. this leaks (3) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLOBAL = this ; a }}; f Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r2 } hb hb? hb If a hb ! f and f hb ! a, thus a = f (anti-symmetry of hb ) However a is cannot be a freeze action! 80 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 81. this leaks (3) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLOBAL = this ; a }}; f Thread 2 T o = GLOBAL ; if (o != null ) { int result = o.fx; r2 } hb hb? hb There is no hb , thus all the cases are possible: result 2 f0; 42g 81 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 82. Unintentional this leak (4) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLb = this ; }}; GLa = l; Thread 2 T u = GLb; T o = GLa; if (o != null ) { int result = o.fx; r2 } Can result become 0? 82 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 83. Unintentional this leak (4) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLb = this ; b }}; f GLa = l; a Thread 2 T u = GLb; T o = GLa; if (o != null ) { int result = o.fx; } hb hb hb? Actions in a thread form happens-before: w hb ! f , f hb ! a 83 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 84. Unintentional this leak (4) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLb = this ; b }}; f GLa = l; a Thread 2 T u = GLb; T o = GLa; ra if (o != null ) { int result = o.fx; } hb hb hb? mc Suppose thread 2 sees GLa, thus a mc ! ra! 84 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 85. Unintentional this leak (4) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLb = this ; b }}; f GLa = l; a Thread 2 T u = GLb; rb T o = GLa; ra if (o != null ) { int result = o.fx; r1 } hb hb hb? mc dr? dr? There should be dr somewhere: rb dr ! r1 or ra dr ! r1 85 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 86. Unintentional this leak (4) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLb = this ; b }}; f GLa = l; a Thread 2 T u = GLb; rb T o = GLa; ra if (o != null ) { int result = o.fx; r1 } hb hb hb? mc dr? dr ! r 1, then we fail, since w hb If rb dr ! r1 can not be completed 86 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 87. Unintentional this leak (4) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 T l = new T() {{ fx = 42; w GLb = this ; b }}; f GLa = l; a Thread 2 T u = GLb; rb T o = GLa; ra if (o != null ) { int result = o.fx; r1 } hb hb hb? mc dr? dr Conclusion: if a thread had ever seen object with unfrozen fields, then there is no final semantics for that object! 87 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 88. Reflection in action (5) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; w1 }}; GLOBAL = t; U w = new U (); w.x = 42; w2 reflectSet (t.fu , w); Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; r2 } Can result become 0? 88 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 89. Reflection in action (5) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; }}; GLOBAL = t; U w = new U (); w.x = 42; w2 reflectSet (t.fu , w); Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; r2 } hb*? We’d better have w2 hb ! r2 (otherwise we must not see the write of 0 in w.x) 89 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 90. Reflection in action (5) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; }}; GLOBAL = t; U w = new U (); w.x = 42; w2 reflectSet (t.fu , w); f2 Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; r2 } hb*? f2 does not work for hb : there is no suitable f 2 hb ! a 90 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 91. Reflection in action (5) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; }}; f1 GLOBAL = t; U w = new U (); w.x = 42; w2 reflectSet (t.fu , w); f2 Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; r2 } hb*? hb? f1 does not work for hb as well: it must be w2 hb ! f 1 91 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 92. Reflection in action (5) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; }}; f1 GLOBAL = t; U w = new U (); w.x = 42; w2 reflectSet (t.fu , w); f2 Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; r2 } hb*? hb? It turns out r2 is not denied to observe 0 92 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 93. Reflection in action (5) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; }}; f1 GLOBAL = t; a U w = new U(); w.x = 42; w2 reflectSet (t.fu , w); f2 Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; r2 } hb*? hb? Conclusion: do not alter the final field after you publish its contents result 2 f0; 1; 42g 93 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 94. Let’s fix reflection (5.1) w hb ! f hb ! a mc ! r1 dr ! r2 T t = new T() {{ fu = new U (); fu.x = 1; }}; U w = new U (); w.x = 42; reflectSet (t.fu , w); GLOBAL = t; a Thread 2 T t = GLOBAL ; if (t != null ) { U u = t.fu; int result = u.x; } If we publish the object after all modifications of final fields, the publication is safe: result 2 f1; 42g 94 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 95. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; GL = a; Thread 2 A a = GL; B = new B() {{ fb = o; }}; GL2 = b; Thread 3 B B = GL2; A a = b.fb; int r = a.fx; r2 Can result become 0? 95 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 96. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; mc A a = b.fb; rb int r = a.fx; r1 mc rb sees wb ) wb mc ! rb ra sees wa : wa mc ! ra 96 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 97. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; mc A a = b.fb; rb int r = a.fx; r1 mc mc Thread 2 writes an address of a foreign-created object, thus ra mc ! wb 97 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 98. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; mc A a = b.fb; rb int r = a.fx; r1 mc mc dr Therad 3 did not create object A, r reads its field, and rb is the only read of A’s address, thus dereference chain: rb dr ! r1 98 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 99. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; mc A a = b.fb; rb int r = a.fx; r1 mc mc dr mc rb dr ! r1 ) rb mc ! r1 99 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 100. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; mc A a = b.fb; rb int r = a.fx; r1 mc mc mc mc mc is transitive (since it is a partial order) ) wa mc ! r1 100 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 101. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; f GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; A a = b.fb; rb int r = a.fx; r1 r2 mc dr Let’s pick r2 = r 1, thus r1 dr ! r2 ( dr is reflexive) 101 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 102. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; f GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; A a = b.fb; rb int r = a.fx; r1 r2 mc dr hb hb hb* Here are all the requirements for HB: w hb ! f hb ! a mc ! r2 ) w hb ! r1 dr ! r2 102 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 103. Final wrapper (6) w hb ! f hb ! a mc ! r1 dr ! r2 Thread 1 A a = new O() {{ fx = 42; w }}; f GL = a; wa Thread 2 A a = GL; ra B = new B() {{ fb = o; wb }}; GL2 = b; Thread 3 B B = GL2; A a = b.fb; rb int r = a.fx; r1 r2 mc dr hb hb hb* (w hb ! r2) ) result 2 f42g 103 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved
  • 104. Questions? 104 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved