Slide 1

Slide 1 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation A practical approach to Java Memory Model A practical approach to Java Memory Model Andrzej Czarny https://www.ocadotechnology.com/

Slide 2

Slide 2 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Ocado Technology Senior Software Engineer - Simulation Algorithm Development

Slide 3

Slide 3 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Contents • Out of order execution • Introduction to JCStress • Basic JMM concepts and definitions • Examples/Puzzles • Future of JMM

Slide 4

Slide 4 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Out of order execution • Compiler optimizations • Hardware CPU cache optimization

Slide 5

Slide 5 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation public class JITOptimization { private static boolean flag = true; public static void main(String ... args) throws InterruptedException { new Thread(JITOptimization::loop).start(); Thread.sleep(1000); new Thread(JITOptimization::terminate).start(); } public static void terminate() { flag = false; System.out.println("Flag has been changed"); } public static void loop() { boolean printOnce = true; while (getFlag()) { if (printOnce) { printOnce = false; System.out.println("I'm in the loop"); } } System.out.println("I'm outside of the loop"); } public static boolean getFlag() { return flag;} } JIT optimization

Slide 6

Slide 6 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation public class JITOptimization { private static boolean flag = true; public static void main(String ... args) throws InterruptedException { new Thread(JITOptimization::loop).start(); Thread.sleep(1000); new Thread(JITOptimization::terminate).start(); } public static void terminate() { flag = false; System.out.println("Flag has been changed"); } public static void loop() { boolean flag = getFlag(); while (flag) { } } public static boolean getFlag() { return flag;} } JIT optimization

Slide 7

Slide 7 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Demo 1

Slide 8

Slide 8 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Processor Symmetric multiprocessing Memory C-1 C-2 C-3 C-4 C-5 Thread 2 C-0 Thread 1

Slide 9

Slide 9 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Processor OutOfOrder execution C-0 Execution Engine Store Buffer L1 L2 L3 C-5 L S Load Buffer Memory r2 = x y:524 Coherence Protocol x = 168 store r1 = y load

Slide 10

Slide 10 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Processor OutOfOrder execution C-0 Execution Engine Store Buffer L1 L2 L3 C-5 L S Load Buffer Memory r2 = x y:524 x = 168 store r1 = y load Coherence Protocol 168

Slide 11

Slide 11 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Processor OutOfOrder execution C-0 Execution Engine Store Buffer L1 L2 L3 C-5 L S Load Buffer Memory r2 = x x = 168 store r1 = y load Coherence Protocol 168 168 168

Slide 12

Slide 12 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Hardware CPU cache optimization Type Alpha ARMv7 POWER SPARC x86 LoadsLoads mb dmb lwsync LoadsStores mb dmb hwsync StoresStores wmb dmb-st lwsync StoresLoads mb dmb hwsync membar mfence locked insn Weak memory model Strong memory model

Slide 13

Slide 13 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation JCStress Tutorial The Java Concurrency Stress tests (jcstress) is an experimental harness and a suite of tests to aid the research in the correctness of concurrency support in the JVM, class libraries, and hardware. http://openjdk.java.net/projects/code-tools/jcstress/

Slide 14

Slide 14 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Test Example public class SomeTest { @JCStressTest @State @Outcome(id="1", expect=Expect.ACCEPTABLE_INTERESTING, desc="special case") public static class Test1 { @Actor public void actor1(II_Result r) {} @Arbiter public void arbiter(II_Result r) {} } @JCStressTest(Mode.Termination) @State public static class Test2 { @Actor public void actor1(II_Result r) {} @Signal public void signal() {} } }

Slide 15

Slide 15 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation StoreLoad reordering @JCStressTest @State public class StoreLoad { int x, y; @Actor public void actor1(II_Result r) { x = 1; //store r.r1 = y; //load } @Actor public void actor2(II_Result r) { y = 1; //store r.r2 = x; // load } }

Slide 16

Slide 16 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Demo 2

Slide 17

Slide 17 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation “The Java Memory Model was the first attempt to provide a comprehensive threading memory model for a popular programming language.” https://en.wikipedia.org/wiki/Memory_model_(programming) Java Memory Model

Slide 18

Slide 18 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation JMM history • Before JSR133 – Not possible to create thread-safe immutable objects – Reordering volatile and non volatile fields • JSR133 – Java 1.5 – Thread-safe immutable object – More powerful volatile

Slide 19

Slide 19 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Synchronized-with relations unlock action on monitor x write to a volatile variable x action that starts a thread final action in a thread all subsequent lock actions on x all subsequent reads of x first action in a thread any action that detects that a thread has terminated Thread A Thread B

Slide 20

Slide 20 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Happens-before Order Thread A Operation 1 Operation 2 Operation 3 synchronized(y) Operation 4 Thread B Operation write volatile z Operation 2 read volatile x synchronized(v) write volatile x Operation 3 Operation 4 Operation 5

Slide 21

Slide 21 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Happens-before Order Order for Thread B Operation 1, 2 results Operation 1 write volatile z Operation 2 read volatile x synchronized(v) Operation 3 write volatile x Thread A Operation 1 Operation 2 Operation 3 synchronized(y) Operation 4 Thread B Operation 1 write volatile z Operation 2 read volatile x synchronized(v) write volatile x Operation 3 Operation 4 Operation 5 Operation 4

Slide 22

Slide 22 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Happens-before Order Order for Thread B Operation 1 write volatile z Operation 2 read volatile x synchronized(v) Operation 3 write volatile x Thread A Operation 1 Operation 2 Operation 3 synchronized(y) Operation 4 Thread B Operation 1 write volatile z Operation 2 read volatile x synchronized(v) write volatile x Operation 3 Operation 4 Operation 5 Operation 4

Slide 23

Slide 23 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation final Fields Semantics

Slide 24

Slide 24 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Thread-safe immutable object @JCStressTest @State public class AmIImmutable { static AmIImmutable i = new AmIImmutable(); int x, y, z; AmIImmutable() { x = 1; y = 2; z = 3; } @Actor public void actor1() { i = new AmIImmutable(); } @Actor public void actor2(III_Result r) { AmIImmutable tmp = i; r.r1 = tmp.x; r.r2 = tmp.y; r.r3 = tmp.z; } }

Slide 25

Slide 25 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Demo 3

Slide 26

Slide 26 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Thread-safe immutable object @JCStressTest @State public class Escape { volatile static IntSupplier supplier; static Escape escape = new Escape(); final int x; public Escape() { supplier = () -> getX(); x = 1; } int getX(){return x;} @Actor public void actor1() { escape = new Escape(); } @Actor public void actor2(II_Result r) { r.r1 = supplier.getAsInt(); r.r2 = escape.getX(); } }

Slide 27

Slide 27 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Demo 4

Slide 28

Slide 28 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation volatile

Slide 29

Slide 29 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Thread-safe immutable object @JCStressTest @State public class AmISynchronized { int y = 1; volatile int x = 1; @Actor public void actor1() { y = 2; x = 3; } @Actor public void actor2(I_Result r) { r.r1 = y * x; } }

Slide 30

Slide 30 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Demo 5

Slide 31

Slide 31 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation What next • JEP 188: Java Memory Model Update – Improve formalization – JVM coverage – Extend scope (AtomicX.weakCompareAndSet) – C11/C++11 compatibility – Implementation guidance. JVM implementors – Testing support – Tool support (static analysis)

Slide 32

Slide 32 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Summary Never ignore concurrency issues! Use highest level of abstraction Check framework requirements regarding concurrency Code against specification not implementation Always use final on immutable classes

Slide 33

Slide 33 text

https://github.com/amczarny/JMMPresentation https://github.com/amczarny/JMMPresentation Q & A