final field semantics

104
Semantics of final fields in java Vladimir Sitnikov, Valentin Kovalenko [email protected], @VladimirSitnikv NetCracker September 2014

Upload: vladimir-sitnikov

Post on 24-Jun-2015

1.062 views

Category:

Documents


0 download

DESCRIPTION

Final keyword in java is known to forbid class extension and modification of the fields. It is less known to have special meaning in multithreaded code. Unfortunately, there is not that much information on the latter, and even most thorough talks avoid deep details on the beauty of finals. In this talk I apply section 17.5 of java language specification to different examples and show how the spec works. Several myths are busted on the way. Here's nice article on different aspects of JMM: http://shipilev.net/blog/2014/jmm-pragmatics/

TRANSCRIPT

Page 1: Final field semantics

Semantics of final fields in java

Vladimir Sitnikov, Valentin [email protected], @VladimirSitnikv

NetCracker

September 2014

Page 2: Final field semantics

Introduction

Examples

2 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 3: Final field semantics

Why final is required inJMM?

3 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 4: Final field semantics

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

Page 5: Final field semantics

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 isinsecure

5 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 6: Final field semantics

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 itvia data race to the checker thread

6 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 7: Final field semantics

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, andthe value depends on String#offset and String#size

7 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 8: Final field semantics

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 observenot-fully-initialized String

8 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 9: Final field semantics

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 thenreadFile might observe "/etc/passwd"

Even synchronization on s and volatile will not help!

9 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 10: Final field semantics

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 thenreadFile might observe "/etc/passwd"Even synchronization on s and volatile will not help!

10 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 11: Final field semantics

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 fromHackThread

11 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 12: Final field semantics

Зачем нам JMM?

12 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 13: Final field semantics

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

Page 14: Final field semantics

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

Page 15: Final field semantics

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

Page 16: Final field semantics

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 alsoexample 17.5.3-1)

16 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 17: Final field semantics

A bit of theory

17 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 18: Final field semantics

Program order

I Program order is a total order among inter-thread actions ofeach thread in source code order

I Compiler is forbidden to reorder/alter/ignore operations ifobservable behavior violates program order

I It does not mean the program is executed in program orderI For instance: program order is not defined for operations onlocal variables

18 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 19: Final field semantics

Program order

I Program order is a total order among inter-thread actions ofeach thread in source code order

I Compiler is forbidden to reorder/alter/ignore operations ifobservable behavior violates program order

I It does not mean the program is executed in program orderI For instance: program order is not defined for operations onlocal variables

19 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 20: Final field semantics

Program order

I Program order is a total order among inter-thread actions ofeach thread in source code order

I Compiler is forbidden to reorder/alter/ignore operations ifobservable 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 onlocal variables

20 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 21: Final field semantics

Program order

I Program order is a total order among inter-thread actions ofeach thread in source code order

I Compiler is forbidden to reorder/alter/ignore operations ifobservable behavior violates program order

I It does not mean the program is executed in program orderI For instance: program order is not defined for operations onlocal variables

21 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 22: Final field semantics

Partial order

I In section 17 JLS "partial order" is mentioned 8 times

I Partial order ishb−−→ a binary relation that is:

I Reflexive: for each element x , xhb−−→ x

I Antisymmetric: if xhb−−→ y and y

hb−−→ x , then x and y are the same

element

I Transitive: if xhb−−→ y and y

hb−−→ z , then x

hb−−→ z

22 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 23: Final field semantics

Partial order

I In section 17 JLS "partial order" is mentioned 8 times

I Partial order ishb−−→ a binary relation that is:

I Reflexive: for each element x , xhb−−→ x

I Antisymmetric: if xhb−−→ y and y

hb−−→ x , then x and y are the same

element

I Transitive: if xhb−−→ y and y

hb−−→ z , then x

hb−−→ z

23 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 24: Final field semantics

Partial order

I In section 17 JLS "partial order" is mentioned 8 times

I Partial order ishb−−→ a binary relation that is:

I Reflexive: for each element x , xhb−−→ x

I Antisymmetric: if xhb−−→ y and y

hb−−→ x , then x and y are the same

element

I Transitive: if xhb−−→ y and y

hb−−→ z , then x

hb−−→ z

24 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 25: Final field semantics

Partial order

I In section 17 JLS "partial order" is mentioned 8 times

I Partial order ishb−−→ a binary relation that is:

I Reflexive: for each element x , xhb−−→ x

I Antisymmetric: if xhb−−→ y and y

hb−−→ x , then x and y are the same

element

I Transitive: if xhb−−→ y and y

hb−−→ z , then x

hb−−→ z

25 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 26: Final field semantics

Partial order

I In section 17 JLS "partial order" is mentioned 8 times

I Partial order ishb−−→ a binary relation that is:

I Reflexive: for each element x , xhb−−→ x

I Antisymmetric: if xhb−−→ y and y

hb−−→ x , then x and y are the same

element

I Transitive: if xhb−−→ y and y

hb−−→ z , then x

hb−−→ z

26 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 27: Final field semantics

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 readsI 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 readI It must still obey other rules, especially: 17.4.8 executions andcausality requirements

27 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 28: Final field semantics

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 readI It must still obey other rules, especially: 17.4.8 executions andcausality requirements

28 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 29: Final field semantics

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 readsI A read either sees the latest write (in hb order)

I Or any write via data race when multiple writes arehb -unordered with the read

I It must still obey other rules, especially: 17.4.8 executions andcausality requirements

29 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 30: Final field semantics

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 readsI 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 andcausality requirements

30 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 31: Final field semantics

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 readsI 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 readI It must still obey other rules, especially: 17.4.8 executions andcausality requirements

31 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 32: Final field semantics

Semantics of final fields

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

I w and r2 – the read and the write in question

I f – freeze of a final field, that is read in r1

32 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 33: Final field semantics

Semantics of final fields

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

I w and r2 – the read and the write in questionI f – freeze of a final field, that is read in r1

33 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 34: Final field semantics

Semantics of final fields

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

I If the only path from write to read follows all this arrows, thenwe must not see earlier writes

I If multiple paths exist, you need to go deeperI We use hb∗ notation to distinguish it from hb and since "thishappens-before ordering does not transitively close with otherhappens-before orderings"

34 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 35: Final field semantics

Semantics of final fields

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

I If the only path from write to read follows all this arrows, thenwe 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 "thishappens-before ordering does not transitively close with otherhappens-before orderings"

35 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 36: Final field semantics

Semantics of final fields

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

I If the only path from write to read follows all this arrows, thenwe must not see earlier writes

I If multiple paths exist, you need to go deeperI We use hb∗ notation to distinguish it from hb and since "thishappens-before ordering does not transitively close with otherhappens-before orderings"

36 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 37: Final field semantics

Freeze action w hb−→ f hb−→ a mc−→ r1 dr−→ r2

Field

Freezes of a final field occur both at the end of the constructor, andimmediately after each modification

37 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 38: Final field semantics

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, andimmediately after each modification

38 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 39: Final field semantics

Freeze action w hb−→ f hb−→ a mc−→ r1 dr−→ r2

Freeze actionField

Freezes of a final field occur both at the end of the constructor, andimmediately after each modification39 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 40: Final field semantics

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 objectI Hence, we must read an address of the object somewhere

I This is called r1dr−→ r2

40 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 41: Final field semantics

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 objectI Current thread did not create the object

I Hence, we must read an address of the object somewhere

I This is called r1dr−→ r2

41 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 42: Final field semantics

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 objectI Current thread did not create the objectI Hence, we must read an address of the object somewhere

I This is called r1dr−→ r2

42 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 43: Final field semantics

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 objectI Current thread did not create the objectI Hence, we must read an address of the object somewhere

I This is called r1dr−→ r2

43 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 44: Final field semantics

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

r1dr−→ r2 (thread 2 reads a field of object created in a foreign thread)

44 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 45: Final field semantics

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 adr−→ r2?

45 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 46: Final field semantics

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

Page 47: Final field semantics

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

Page 48: Final field semantics

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 radr−→ r2 or rb

dr−→ r2 must exist, however no one can tell

which one48 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 49: Final field semantics

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 w1mc−−→ r1

49 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 50: Final field semantics

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 r1mc−−→ w2

50 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 51: Final field semantics

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 ⇒ w2mc−−→ r3

51 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 52: Final field semantics

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

r3dr−→ r4 (read of a object’s field)

⇒ r3mc−−→ r4

52 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 53: Final field semantics

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

r3dr−→ r4 (read of a object’s field) ⇒ r3

mc−−→ r4

53 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 54: Final field semantics

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) ⇒ w1mc−−→ r4

54 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 55: Final field semantics

Introduction

Examples

55 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 56: Final field semantics

Disclaimer

I All the examples contain data races (why bother otherwise?)

I We do not consider cases when null is observed (those cases arenot interesting)

I Lots of brains were hurt when preparing the slides

56 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 57: Final field semantics

Disclaimer

I All the examples contain data races (why bother otherwise?)I We do not consider cases when null is observed (those cases arenot interesting)

I Lots of brains were hurt when preparing the slides

57 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 58: Final field semantics

Disclaimer

I All the examples contain data races (why bother otherwise?)I We do not consider cases when null is observed (those cases arenot interesting)

I Lots of brains were hurt when preparing the slides

58 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 59: Final field semantics

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

Page 60: Final field semantics

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:

whb−−→ f , f

hb−−→ a

60 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 61: Final field semantics

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 :

amc−−→ r0

61 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 62: Final field semantics

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 theonly read of the address, thus we have dereference chain:

r0dr−→ r1

62 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 63: Final field semantics

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

r0dr−→ r1⇒ r0

mc−−→ r1

63 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 64: Final field semantics

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

amc−−→ r1 ( mc is transitive)

64 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 65: Final field semantics

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 = r1, then r1dr−→ r2 ( dr is reflexive)

65 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 66: Final field semantics

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∗:

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

66 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 67: Final field semantics

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*

(whb∗

−−→ r2)⇒ result ∈ {42}

67 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 68: Final field semantics

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

Page 69: Final field semantics

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:

whb−−→ f , f

hb−−→ a

69 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 70: Final field semantics

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):

amc−−→ r1

70 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 71: Final field semantics

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 isthe only read of the address of the array, thus dereference chain:

r1dr−→ r2

71 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 72: Final field semantics

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∗:

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2

72 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 73: Final field semantics

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*

(whb∗

−−→ r2)⇒ result ∈ {42}

73 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 74: Final field semantics

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

Page 75: Final field semantics

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

}

hbhb

mc

dr

hb∗

We compose hb∗ exactly as in the previous example

75 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 76: Final field semantics

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

}

hbhb

mc

dr

hb∗

(whb∗

−−→ r2)⇒ result ∈ {42}The result does not depend on the order of assignment to final fields!

76 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 77: Final field semantics

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

Page 78: Final field semantics

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:

whb−−→ f , a

hb−−→ f

78 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 79: Final field semantics

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 fhb−−→ a!

79 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 80: Final field semantics

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 ahb−−→ 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

Page 81: Final field semantics

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 ∈ {0, 42}

81 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 82: Final field semantics

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

Page 83: Final field semantics

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:

whb−−→ f , f

hb−−→ a

83 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 84: Final field semantics

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 amc−−→ ra!

84 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 85: Final field semantics

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: rbdr−→ r1 or ra

dr−→ r1

85 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 86: Final field semantics

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

If rbdr−→ r1, then we fail, since w

hb∗

−−→ r1 can not be completed

86 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 87: Final field semantics

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

Page 88: Final field semantics

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

Page 89: Final field semantics

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 w2hb∗

−−→ r2 (otherwise we must not see the writeof 0 in w.x)

89 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 90: Final field semantics

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 2hb−−→ a

90 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 91: Final field semantics

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 w2hb−−→ f 1

91 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 92: Final field semantics

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

Page 93: Final field semantics

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 contentsresult ∈ {0, 1, 42}

93 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 94: Final field semantics

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, thepublication is safe: result ∈ {1, 42}

94 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 95: Final field semantics

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

Page 96: Final field semantics

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;

A a = b.fb; rb

int r = a.fx; r1

mc

mc

rb sees wb ⇒ wbmc−−→ rb

ra sees wa : wamc−−→ ra

96 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 97: Final field semantics

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;

A a = b.fb; rb

int r = a.fx; r1

mc

mc

mc

Thread 2 writes an address of a foreign-created object, thus

ramc−−→ wb

97 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 98: Final field semantics

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;

A a = b.fb; rb

int r = a.fx; r1

mc

mc

mcdr

Therad 3 did not create object A, r reads its field, and rb is theonly read of A’s address, thus dereference chain:

rbdr−→ r1

98 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 99: Final field semantics

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;

A a = b.fb; rb

int r = a.fx; r1

mc

mc

mcdr

mc

rbdr−→ r1⇒ rb

mc−−→ r1

99 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 100: Final field semantics

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;

A a = b.fb; rb

int r = a.fx; r1

mc

mc

mc

mc

mc

mc is transitive (since it is a partial order) ⇒ wamc−−→ r1

100 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 101: Final field semantics

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 = r1, thus r1dr−→ r2 ( dr is reflexive)

101 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 102: Final field semantics

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∗:

whb−−→ f

hb−−→ a

mc−−→ r1

dr−→ r2⇒ w

hb∗

−−→ r2102 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 103: Final field semantics

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*

(whb∗

−−→ r2)⇒ result ∈ {42}

103 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved

Page 104: Final field semantics

Questions?

104 / 104 (c) Copyright 2014, NetCracker Technology Corp. All rights reserved