Николай Папирный Тема: "Java memory model для простых смертных"

Post on 12-Jul-2015

817 views 1 download

Transcript of Николай Папирный Тема: "Java memory model для простых смертных"

Java Memory Model

for mortals

Nikolas Papirniy

Java and c++ developers

C++ dev: DEPENDS ON

IMPLEMENTATION!

Java dev: Wait, I didn’t ask a

question

Java dev: May I…...

Why should I spend time on JMM?

Why should I spend time on JMM?

It’s getting asked on job interviews!

Why should I spend time on JMM

Why not everyone knows JMM?

JMM is important!

Today’s goal!

Agenda?

1. Program Order

2. Memory Model

3. Sequential Consistency

4. Synchronization action

5. Synchronization order

6. Synchronezed with

7. Happens-before

8. Double checked locking

Baruch about concurrency

In this case, you can shoot

yourself in any limb of any

caliber!

Is it about Shipilev?

Java Memory Model Pragmatics

There is a little problem

Who visit Shipilev’s presentations?

1) Those who don’t understand Shipilev

2) Those who think they understand Shipilev

3) Shipilev

What was before JMM?

Single threaded

1. int a = 2;

2. int b = 2;

3. int c = a + b

4. System.out.println(c);

Program Order

?

Single threaded

What have we learned?

1. Program order

What about now?

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

?

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

A

v = 10;

v = 20;

print v

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

A

v = 10;

v = 20;

print v

B

v = 20;

v = 10;

print v

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

A

v = 10;

v = 20;

print v

B

v = 20;

v = 10;

print v

C

v = 20;

print v

v = 10

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

A

v = 10;

v = 20;

print v

B

v = 20;

v = 10;

print v

C

v = 20;

print v

v = 10

D

print v

v = 20;

v = 10

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

A

v = 10;

v = 20;

print v

B

v = 20;

v = 10;

print v

C

v = 20;

print v

v = 10

D

print v

v = 20;

v = 10

WAT?

Situation….

1. Compiler

2. Runtime

3. Hardware

Hello memory model!

Memory model QUESTION

What will you see in a certain moment of

program execution?

What is Java Memory Model

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

A

v = 10;

v = 20;

print v

B

v = 20;

v = 10;

print v

C

v = 20;

print v

v = 10

D

print v

v = 20;

v = 10

What have we learned?

1. Program order

2. Memory model

Sequentially consistent

(Lamport 1979)

1. Executing instructions one at a time

2. Each instruction see result of previos

instructions

3. Total order is consistent with Program Order

Sequentially consistent

1

5

3

4

2

Multi-core heaven?

Caches

Cache line

Cache 1

Cache line

64 bytes

read variable

Cache line

Cache 1

Cache line

Cache line

What have we learned?

1. Program order

2. Memory model

3. Sequential Consistency

SC Reality: concurrency

1

write

1

5

read

4

2

Data race

If:

1. Several threads access one variable

2. One thread writes

3. No synchronization

Data race

Thread 1 Thread 2

Shared memoryA

Tread 1: read A

Thread 1 Thread 2

Shared memoryA

Tread 1: read A (cont)

A

Thread 1 Thread 2

Shared memoryA

Tread 2: read A

A A

Thread 1 Thread 2

Shared memoryA

Thread 1: write A

AA

Thread 1 Thread 2

Shared memoryA

Thread 2: write A

AA

Thread 1 Thread 2

Shared memoryA

Thread 1: memory flushes to main memory

AA

A

Thread 1 Thread 2

Shared memoryA

Thread 2: memory flushes to main memory

AA

AA

Thread 1 Thread 2

Shared memoryA

Read from local variable

AA

AA

!

Synchronization

read

write read

write

Synchronization

read write

Synchronization action

➔Read / write volatile

➔Lock / unlock monitor

➔And other

Read / write volatile

volatile int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

SA

Read / write volatile

volatile int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

SA

Read / write volatile

volatile int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

SA

Read / write volatile

volatile int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

SA

Lock / unlock monitor

Object lock = new Object();

Thread 1 Thread 2

1a. synchronized(lock) {

2a. // actions

3a. }

1b. synchronized(lock) {

2b. // actions

3b. }

SA

Lock / unlock monitor

Object lock = new Object();

Thread 1 Thread 2

1a. synchronized(lock) {

2a. // actions

3a. }

1b. synchronized(lock) {

2b. // actions

3b. }

SA

Lock / unlock monitor

Object lock = new Object();

Thread 1 Thread 2

1a. synchronized(lock) {

2a. // actions

3a. }

1b. synchronized(lock) {

2b. // actions

3b. }

SA

Lock / unlock monitor

Object lock = new Object();

Thread 1 Thread 2

1a. synchronized(lock) {

2a. // actions

3a. }

1b. synchronized(lock) {

2b. // actions

3b. }

SA

Lock / unlock monitor

Object lock = new Object();

Thread 1 Thread 2

1a. synchronized(lock) {

2a. // actions

3a. }

1b. synchronized(lock) {

2b. // actions

3b. }

SA

SC Reality: visibility

20

int v = 0;

Thread 1 Thread 2

1a. v = 10; 1b. v = 20;

2b. System.out.println(v);

B

v = 20;

v = 10;

print v

What have we learned?

1. Program order

2. Memory model

3. Sequential Consistency

4. Synchronization action

Visibility of volatile variables

Thread 1 Thread 2

Shared memoryA

Thead 1: read A

read barrier

Thread 1 Thread 2

Shared memoryA

Thead 1: read A (cont)

A

Thread 1 Thread 2

Shared memoryA

Thead 2: read A

A

read barrier

A

Thread 1 Thread 2

Shared memoryA

Thead 1: write A

AA

write barrier

A

Thread 1 Thread 2

Shared memoryA

Thead 2: write A

AA

write barrier

A

Thread 1 Thread 2

Shared memoryA

Thead 2: write A

AA

write barrier

AAA

Thread 1 Thread 2

Shared memoryA

Thead 1: read A

A

A

read barrier

A

A

A

A A

SC Reality: atomicity

long v = 0L;

Thread 1 Thread 2

v = Long.MAX_VALUE; System.out.println(v);

A. Long.MAX_VALUE B. 0L

C. FFFF FFFF 0000 0000 D. 0000 0000 FFFF FFFF

SC Reality: atomicity

long v = 0L;

Thread 1 Thread 2

v = Long.MAX_VALUE; System.out.println(v);

A. Long.MAX_VALUE B. 0L

C. FFFF FFFF 0000 0000 D. 0000 0000 FFFF FFFF

SC Reality: atomicity

Atomicity JMM

A single write to a non-volatile long or double

value is treated as two separate writes: one to

each 32-bit half.

SC Reality: atomicity - SOLUTION

AtomicLong v = new AtomicLong(0L);

Thread 1 Thread 2

l.set(Long.MAX_VALUE); System.out.println(v.get());

A. Long.MAX_VALUE B. 0L

C. FFFF FFFF 0000 0000 D. 0000 0000 FFFF FFFF

SC Reality: atomicity - SOLUTION

AtomicLong v = new AtomicLong(0L);

Thread 1 Thread 2

l.set(Long.MAX_VALUE); System.out.println(v.get());

A. Long.MAX_VALUE B. 0L

C. FFFF FFFF 0000 0000 D. 0000 0000 FFFF FFFF

How?

Synchronization order

1

2

44

SA

SA

SA

SA

Thread 1 Thread 2

55

3

3

12

Synchronization order

volatile int x, y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

Synchronization order (1)

volatile int x, y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

Synchronization order (2)

volatile int x, y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

Synchronization order (3)

volatile int x, y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

Synchronization order (4)

volatile int x, y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

?

Synchronization order (4)

volatile int x, y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

Synchronization order consistent with Program Order

What have we learned?

1. Program order

2. Memory model

3. Sequential Consistency

4. Synchronization action

5. Synchronization order

Synchronizes with

2

1

3

2

1

4 4

3

SA

SA

Thread 1 Thread 2

Synchronizes-with Consistency

● volatile read - can read nearest volatile write

on SO

● monitor unlock - can release nearest monitor

lock on SO

Synchronizes-with

int x;

volatile int y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

write x: 10

read y: ? read x: ?

write y: 20

Synchronizes-with

int x;

volatile int y;

Thread 1 Thread 2

x = 10;

int result1 = y;

y = 20;

int result2 = x;

write x: 10

read y: ? read x: ?

write y: 20SW

Write y

Read y

SW

What have we learned?

1. Program order

2. Memory model

3. Sequential Consistency

4. Synchronization action

5. Synchronization order

6. Synchronezed with

2

1

3

2

4

1

4

3

SA

SA

Thread 1 Thread 2

5 5

One more thing

One more thing

2

1

3

2

4

1

4

3

SA

SA

Thread 1 Thread 2

5 5

PO

PO

One more thing

2

1

3

2

4

1

4

3

SA

SA

Thread 1 Thread 2

5 5

PO

PO

SW

Happens-before!

2

1

3

2

4

1

4

3

SA

SA

Thread 1 Thread 2

5 5

PO

PO

SW

Happens-before

Program OrderSynchronizati

on Order

Synchronizes

With

Happens-before

Visibility

Happens-before for smarties

HB = {PO & SW}+

What have we learned?

1. Program order

2. Memory model

3. Sequential Consistency

4. Synchronization action

5. Synchronization order

6. Synchronezed with

7. Happens-before

Double checked locking

public static class SingletonFactory{

private Singleton instance;

public Singleton getInstance () {

if ( instance == null ) {

synchronized ( this ) {

if ( instance == null ) {

instance = new Singleton ();

}

}

}

return instance ;

}

}

public static class Singleton {

public Integer x;

public Singleton () { x = 42; }

}

Double checked locking

public static class SingletonFactory{

private Singleton instance;

public Singleton getInstance () {

if ( instance == null ) {

synchronized ( this ) {

if ( instance == null ) {

instance = alloc + Singleton object copy

instance.x = 42

}

}

}

return instance ;

}

}

public static class Singleton {

public Integer x;

public Singleton () { x = 42; }

}

Constructor inline

Double checked locking

public static class SingletonFactory{

private Singleton instance;

public Singleton getInstance () {

if ( instance == null ) {

synchronized ( this ) {

if ( instance == null ) {

instance = new Singleton ();

}

}

}

return instance ;

}

}

public static class Singleton {

public Integer x;

public Singleton () { x = 42; }

}

Returns null

Double checked locking

public static class SingletonFactory{

private Singleton instance;

public Singleton getInstance () {

if ( instance == null ) {

synchronized ( this ) {

if ( instance == null ) {

instance = new Singleton ();

}

}

}

return instance ;

}

}

public static class Singleton {

public Integer x;

public Singleton () { x = 42; }

}

Returns null

Double checked locking solution

public static class SingletonFactory{

private volatile Singleton instance;

public Singleton getInstance () {

if ( instance == null ) {

synchronized ( this ) {

if ( instance == null ) {

instance = new Singleton ();

}

}

}

return instance;

}

}

public static class Singleton {

public Integer x;

public Singleton () { x = 42; }

}

What have we learned?

1. Program order

2. Memory model

3. Sequential Consistency

4. Synchronization action

5. Synchronization order

6. Synchronezed with

7. Happens-before

8. Double checked locking

Reading