The following is intended to outline our general product direction. It is intended for information purposes
only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code,
or functionality, and should not be relied upon in making purchasing decisions. The development,
release, timing, and pricing of any features or functionality described for Oracle’s products may change
and remains at the sole discretion of Oracle Corporation.
Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and
prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed
discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and
Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q
under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website
at http://www.oracle.com/investor. All information in this presentation is current as of September 2019
and Oracle undertakes no duty to update any statement in light of new information or future events.
Safe Harbor
Copyright © 2019 Oracle and/or its affiliates.
Java Concurrency,
A(nother) Peek Under the Hood
[DEV4211]
Principal Member of Technical Staff
Java Platform Group
September 19, 2019
David Buck
Copyright © 2019 Oracle and/or its affiliates.
IoT Microservices DevOps in the Cloud
Copyright © 2019 Oracle and/or its affiliates.
IoT Microservices DevOps in the Cloud
Copyright © 2019 Oracle and/or its affiliates.
IoT Microservices DevOps in the Cloud
Copyright © 2019 Oracle and/or its affiliates.
JVM Sustaining Engineer
OpenJDK Update Project
Maintainer
JavaOne Rock Star
Co-author of Oracle WebLogic
Server 11g 構築・運用ガイド
@DavidBuckJP
https://blogs.oracle.com/buck/
Who am I? David Buck (left)
Program Agenda
Introduction
Background
Tangent 1: Special Relativity
History
Implementation
Tangent 2: HSDIS
Future
Conclusions
1
2
3
4
5
7
6
Introduction
Motivation
“But I don’t write multithreaded code…”
Web Server
picture: Coolcaesar at the English language Wikipedia [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/)]
GUI
Libraries
picture: David Vignoni / ICON KING (http://icon-king.com) [LGPL (http://www.gnu.org/licenses/lgpl.html) or LGPL (http://www.gnu.org/licenses/lgpl.html)]
Batch Processing
picture: US Social Security Administration (http://www.ssa.gov/history/acalcs.html) [Public domain]
“But I don’t write multithreaded code…”
“But I don’t write multithreaded code…”
Race Conditions
picture: Sakurambo at English Wikipedia [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/)]
Heisenbugs
Bug Heisenberg
Heisenbug
picture: Bundesarchiv, Bild 183-R57262 / Unknown / CC-BY-SA 3.0 [CC BY-SA 3.0 de (http://creativecommons.org/licenses/by-sa/3.0/de/deed.en)]
Observer Effect
picture: Christian Schirm (Own work) [CC0]
Avoiding Heisenbugs
Java Memory Model
synchronized keyword
java.util.concurrent
Avoiding Heisenbugs
Java Memory Model
synchronized keyword
java.util.concurrent
• Don’t do XXX
• You must do YYY
a² + b² == c²
picture: WTF Public License, Version 2
Background
Memory Model
Memory Model
Definition 1
Specification that explains when we can guarantee that a written
value may be read correctly
void hogeMethod1() {
int localA = 42;
assert localA == 42;
}
static int staticA;
void hogeMethod2() {
staticA = 42;
assert staticA == 42;
}
int data = 0;
boolean ready = false;
void hoge3() {
while (!ready) {};
assert data == 42;
}
void hoge4() {
data = 42;
ready = true;
}
Culprit #1
Culprit #2
Memory Ordering
void hoge5() {
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
a = a + 1;
}
Memory Ordering
void hoge5() {
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
a = a + 1;
}
void hoge5() {
a = 2;
b = 2;
c = 3;
d = 4;
e = 5;
}
Memory Ordering
void hoge5() {
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
a = a + 1;
}
void hoge5() {
b = 2;
c = 3;
d = 4;
e = 5;
a = 2;
}
Rule
Single threaded behavior must never change
Out of Order Execution
picture: Amit6, original version (File:Superscalarpipeline.png) by User:Poil (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)]
CPU Differences
Type Alpha ARMv7
PA-
RISC
POWER
SPARC
RMO
SPARC
PSO
SPARC
TSO
x86
x86
oostore
AMD64 IA-64 zSeries
load-
load
Y Y Y Y Y Y Y
load-
store
Y Y Y Y Y Y Y
store-
store
Y Y Y Y Y Y Y Y
store-
load
Y Y Y Y Y Y Y Y Y Y Y Y
Atomic
(loads)
Y Y Y Y Y
Atomic
(stores)
Y Y Y Y Y Y
Depend
ent
loads
Y
instruct
ion
cache
Y Y Y Y Y Y Y Y Y Y
chart source: https://en.wikipedia.org/wiki/Memory_ordering
CPU Differences
Loose Strict
Alpha
X86
CPU Differences
Loose Strict
Memory Barriers
int data = 0;
boolean ready = false;
void hoge3() {
while (!ready) {};
assert data == 42;
}
void hoge4() {
data = 42;
ready = true;
}
Memory Barriers
int data = 0;
boolean ready = false;
void hoge3() {
while (!ready) {};
assert data == 42;
}
void hoge4() {
data = 42;
ready = true;
}
Memory Barriers
int data = 0;
boolean ready = false;
void hoge3() {
while (!ready) {};
assert data == 42;
}
void hoge4() {
data = 42;
ready = true;
}
Memory Barriers Types
store-store
store-load
load-store
load-load
Compiler Barriers
GCC
__asm__ __volatile__("":::"memory");
VC++
_ReadBarrier
_WriteBarrier
_ReadWriteBarrier
Tangent 1: Special Relativity
picture: Sakurambo (Own work) [Public domain]
Tangent 1: Special Relativity
A
B
C
Tangent 1: Special Relativity
A
B
C
A, B, C
Tangent 1: Special Relativity
A
B
C
A, B, C C, B, A
Tangent 1: Special Relativity
Observed order depends on viewer's frame of reference
A
B
C
A, B, C C, B, A
No single “correct” timeline
Special Relativity
Observed order of events depends on frame of reference
No single “correct” timeline
Special Relativity
Observed order of events depends on frame of reference
Multithreaded Code
Observed order of events depends on thread
Memory Model
Definition 2
Clarify what multithreaded behavior developers may depend on
Memory Model
Definition 2
Clarify what multithreaded behavior developers may depend on
Limits what types of optimizations the runtime may do
History
Java Memory Model (JMM)
Write once, run anywhere
1995
Part of the formal language
specification
Happened-before
picture: Peter Campbell [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 4.0-3.0-2.5-2.0-1.0 (http://creativecommons.org/licenses/by-sa/4.0-3.0-2.5-2.0-1.0)]
happened-before
Leslie Lamport
LaTex
happened-before
picture: Leslie Lamport [GFDL (http://en.wikipedia.org/wiki/GFDL]
happened-before
void hoge5() {
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
a = a + 1;
}
happened-before
void hoge4() {
data = 42;
ready = true;
}
void hoge3() {
while (!ready) {};
assert data == 42;
}
happened-before
void hoge4() {
data = 42;
ready = true;
}
void hoge3() {
while (!ready) {};
assert data == 42;
}
happened-before
void synchronized hoge4() {
data = 42;
ready = true;
}
void synchronized hoge3() {
while (!ready) {};
assert data == 42;
}
Warning: if hoge3 is executed first, the above code will deadlock
happened-before
void synchronized hoge4()
{
data = 42;
ready = true;
}
void synchronized hoge3()
{
while (!ready) {};
assert data == 42;
}
Warning: if hoge3 is executed first, the above code will deadlock
JMM Specification
Original JMM Keywords
synchronized
mutual exclusion
happened-before
Original JMM Keywords
synchronized
mutual exclusion
happened-before
volatile
Visibility
Problems with the Original JMM
volatile does not establish a happened-before relationship
final values can change
Many important runtime optimization were not allowed
Doug Lea
Author of the Java Multithreaded
bible
Introduced his own OSS high-
level multithreaded library
Java SE 5.0
Modern JMM introduced
Lea’s library added to official JDK
picture: Zvi Roger [CC BY 3.0 (http://creativecommons.org/licenses/by/3.0)]
Modern JMM
JSR-133
Fixed shortcomings in original JMM
volatile does establish happens-before
final values will never change
Modern JMM Keywords
synchronized
mutual exclusion
happened-before
volatile
visibility
happened-before
final
immutability
JSR-133 の volatile
void hoge4() {
data = 42;
ready = true;
}
void hoge3() {
while (!ready) {};
assert data == 42;
}
Warning: if hoge3 is executed first, the above code will deadlock
volatile boolean ready = false;
volatile != atomic
volatile int id = 0;
int incID() {
return id++;
}
volatile != atomic
volatile int id = 0;
int incID() {
return id++;
}
reg = [id]
reg++
[id] = reg
volatile != atomic
volatile int id = 0;
synchronized int incID() {
return id++;
}
64-bit updates are not guaranteed atomic
• Reads and Writes to long and double values may not happen
atomically
• Possible to read a mix of two different writes
Copyright © 2019 Oracle and/or its affiliates.
Old value MSB New value LSB
happened-before
Monitor (acquisition / release)
Volatile (read / write)
final “freeze” (constructor)
JNI
System.out.println()
Input / Output
thread start()/join()
operations on j.u.concurrent collections
java.util.concurent
JSR-166
Doug Lea’s OSS multithreading library
Multithreaded Control
java.util.concurent
synchronized
wait()/notify()
volatile / final
Abstract
Low-level
Fork/Join (JDK 7)
Functional Programming (JDK 8)
Lambda Forms
Stream API
λ
Var Handles
• Lower-level than volatile / final
• Allows a value to be volatile only when we want it to be
• Explicate fence and acquire / release semantics
• Added in JDK 9 to replace several use cases previously only
supported with sun.misc.Unsafe
Copyright © 2019 Oracle and/or its affiliates.
Implementation
Tangent 2: HSDIS (HotSpot
Disassembler)
Lets us see code generated by JIT
Requires a disassembler plugin
GNU binutils-based plugin
base-hsdis
Command line options
+PrintAssembly
+CompileCommand=print,*MyClass.myMethod
Demos
ARM Assembly Crash Course
ARM Assembly Crash Course
Op Target Source
ARM Assembly Crash Course
MOV r02 #42
ARM Assembly Crash Course
MOV r02 #42
r02 = 42
ARM Assembly Crash Course
Op Target Source
ARM Assembly Crash Course
Op Target Source
Exception
STR Source Target
ARM Assembly Crash Course
MOV
Copies registers
MOV r02 r03
Writes Literals
MOV r02 #42
ARM Assembly Crash Course
LDx
Loads data from memory to a register
ldr r03, [r06]
r03 = *r06
ARM Assembly Crash Course
CMP / BEQ
Compare and branch if equal
cmp r0, #0
beq 0x74178d08
if (r0 == 0) goto 0x74178d08
ARM Assembly Crash Course
DMB
Data Memory Barrier
dmb st
dmb sy
One more thing…
Safe Points
Methods proactively poll
JVM makes page unreadable to stop the world
movw ip, #45056 ; 0xb000
movt ip, #30461 ; 0x76fd
ldr ip, [ip] ; {poll_return}
Long Value
static long val = 0;
public static void main(String[] args) {
new Thread(() -> { while(true) val = -1L; } ).start();
new Thread(() -> { while(true) val = 0L; } ).start();
while (true) {
long temp = val;
if ( temp != -1 && temp != 0 ) {
System.out.println("temp (DEC): " + temp);
System.out.println("temp (BIN): " + Long.toBinaryString(temp));
System.exit(-1);
}
}
}
Object Initialization
public class ObjInit {
static ObjInit globalRef = new ObjInit();
long number;
public ObjInit() {
number = 42;
}
Object Initialization
public static void main(String[] args) {
new Thread(()
-> { while(true) {
long temp = globalRef.number;
if (temp != 42) {
System.out.println(temp);
System.exit(-1);
}
}
} ).start();
new Thread(()
-> { while(true) globalRef = new ObjInit(); } ).start(); }}
public class Loop extends Thread {
static boolean done = false;
public static void main(String[] args) {
Thread childThread = new Loop();
childThread.start();
System.out.println("Starting loop");
spinWait();
System.out.println("Exited loop");
}
private static void spinWait() {
while (!done) ;
}
public void run() {
try {
Thread.sleep(5 * 1000);
} catch (Exception e) {}
done = true;
}
} // class Loop
Loop
Future
JEP-188/JMM9
Not delivered with JDK 9 (JMM9 != JDK 9)
JVM-level specification
Compatibility with C11/C++11
Cover new features added since JDK 5
(e.g. AtomicX.weakCompareAndSet())
Conclusions
Avoid low-level API
java.util.concurent
synchronized
wait()/notify()
volatile / final
Var handles
Abstract
Low-level
Code against the specification
Intermittent bugs are common
Behavior changes with JRE / platform
Stuff to avoid
synchronized (new Object()) { }
Randomly adding volatile declarations until it magically starts working
Testing
As close to production environment as possible
Same hardware
Same JRE (including version)
Same settings
Testing
As much variety as possible
Various hardware
Various JREs (including version)
Various settings
Java Concurrency in Practice
Java Concurrency Bible
Covers JSR-133 / JSR-166
Summary
Avoid low-level APIs
Code against the standard, not the implementation
Testing is always indispensible
Must read Java Concurrency in Practice (JCiP)
Thank You!!!
[ JSR 133 (Java Memory Model) FAQ ]
https://www.cs.umd.edu/~pugh/java/
memoryModel/jsr-133-faq.html
[ Java Concurrency in Practice ]
http://jcip.net/
[ Concurrent Programming in Java ]
http://gee.cs.oswego.edu/dl/cpj/
[ The JSR-133 Cookbook for Compiler Writers ]
http://gee.cs.oswego.edu/dl/jmm/cook
book.html
[ PrintAssembly ]
https://wiki.openjdk.java.net/display/H
otSpot/PrintAssembly
[ BASIC DISASSEMBLER PLUGIN FOR
HOTSPOT DOWNLOADS ]
https://kenai.com/projects/base-
hsdis/downloads
References
Session Survey
Help us make the content
even better. Please complete
the session survey in the
Mobile App.
Copyright © 2019 Oracle and/or its affiliates.
The preceding is intended to outline our general product direction. It is intended for information purposes
only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code,
or functionality, and should not be relied upon in making purchasing decisions. The development,
release, timing, and pricing of any features or functionality described for Oracle’s products may change
and remains at the sole discretion of Oracle Corporation.
Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and
prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed
discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and
Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q
under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website
at http://www.oracle.com/investor. All information in this presentation is current as of September 2019
and Oracle undertakes no duty to update any statement in light of new information or future events.
Safe Harbor
Copyright © 2019 Oracle and/or its affiliates.

Java Concurrency, A(nother) Peek Under the Hood [Code One 2019]

  • 1.
    The following isintended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2019 Oracle and/or its affiliates.
  • 2.
    Java Concurrency, A(nother) PeekUnder the Hood [DEV4211] Principal Member of Technical Staff Java Platform Group September 19, 2019 David Buck Copyright © 2019 Oracle and/or its affiliates.
  • 3.
    IoT Microservices DevOpsin the Cloud Copyright © 2019 Oracle and/or its affiliates.
  • 4.
    IoT Microservices DevOpsin the Cloud Copyright © 2019 Oracle and/or its affiliates.
  • 5.
    IoT Microservices DevOpsin the Cloud Copyright © 2019 Oracle and/or its affiliates.
  • 6.
    JVM Sustaining Engineer OpenJDKUpdate Project Maintainer JavaOne Rock Star Co-author of Oracle WebLogic Server 11g 構築・運用ガイド @DavidBuckJP https://blogs.oracle.com/buck/ Who am I? David Buck (left)
  • 7.
    Program Agenda Introduction Background Tangent 1:Special Relativity History Implementation Tangent 2: HSDIS Future Conclusions 1 2 3 4 5 7 6
  • 8.
  • 9.
    Motivation “But I don’twrite multithreaded code…”
  • 10.
    Web Server picture: Coolcaesarat the English language Wikipedia [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/)]
  • 11.
  • 12.
    Libraries picture: David Vignoni/ ICON KING (http://icon-king.com) [LGPL (http://www.gnu.org/licenses/lgpl.html) or LGPL (http://www.gnu.org/licenses/lgpl.html)]
  • 13.
    Batch Processing picture: USSocial Security Administration (http://www.ssa.gov/history/acalcs.html) [Public domain]
  • 14.
    “But I don’twrite multithreaded code…”
  • 15.
    “But I don’twrite multithreaded code…”
  • 16.
    Race Conditions picture: Sakuramboat English Wikipedia [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/)]
  • 17.
    Heisenbugs Bug Heisenberg Heisenbug picture: Bundesarchiv,Bild 183-R57262 / Unknown / CC-BY-SA 3.0 [CC BY-SA 3.0 de (http://creativecommons.org/licenses/by-sa/3.0/de/deed.en)]
  • 18.
    Observer Effect picture: ChristianSchirm (Own work) [CC0]
  • 19.
    Avoiding Heisenbugs Java MemoryModel synchronized keyword java.util.concurrent
  • 20.
    Avoiding Heisenbugs Java MemoryModel synchronized keyword java.util.concurrent • Don’t do XXX • You must do YYY
  • 21.
    a² + b²== c²
  • 22.
    picture: WTF PublicLicense, Version 2
  • 23.
  • 24.
  • 25.
    Memory Model Definition 1 Specificationthat explains when we can guarantee that a written value may be read correctly
  • 26.
    void hogeMethod1() { intlocalA = 42; assert localA == 42; }
  • 27.
    static int staticA; voidhogeMethod2() { staticA = 42; assert staticA == 42; }
  • 28.
    int data =0; boolean ready = false; void hoge3() { while (!ready) {}; assert data == 42; } void hoge4() { data = 42; ready = true; }
  • 29.
  • 30.
  • 31.
    Memory Ordering void hoge5(){ a = 1; b = 2; c = 3; d = 4; e = 5; a = a + 1; }
  • 32.
    Memory Ordering void hoge5(){ a = 1; b = 2; c = 3; d = 4; e = 5; a = a + 1; } void hoge5() { a = 2; b = 2; c = 3; d = 4; e = 5; }
  • 33.
    Memory Ordering void hoge5(){ a = 1; b = 2; c = 3; d = 4; e = 5; a = a + 1; } void hoge5() { b = 2; c = 3; d = 4; e = 5; a = 2; }
  • 34.
  • 35.
    Out of OrderExecution picture: Amit6, original version (File:Superscalarpipeline.png) by User:Poil (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)]
  • 36.
    CPU Differences Type AlphaARMv7 PA- RISC POWER SPARC RMO SPARC PSO SPARC TSO x86 x86 oostore AMD64 IA-64 zSeries load- load Y Y Y Y Y Y Y load- store Y Y Y Y Y Y Y store- store Y Y Y Y Y Y Y Y store- load Y Y Y Y Y Y Y Y Y Y Y Y Atomic (loads) Y Y Y Y Y Atomic (stores) Y Y Y Y Y Y Depend ent loads Y instruct ion cache Y Y Y Y Y Y Y Y Y Y chart source: https://en.wikipedia.org/wiki/Memory_ordering
  • 37.
  • 38.
  • 39.
    Memory Barriers int data= 0; boolean ready = false; void hoge3() { while (!ready) {}; assert data == 42; } void hoge4() { data = 42; ready = true; }
  • 40.
    Memory Barriers int data= 0; boolean ready = false; void hoge3() { while (!ready) {}; assert data == 42; } void hoge4() { data = 42; ready = true; }
  • 41.
    Memory Barriers int data= 0; boolean ready = false; void hoge3() { while (!ready) {}; assert data == 42; } void hoge4() { data = 42; ready = true; }
  • 42.
  • 43.
  • 45.
    Tangent 1: SpecialRelativity picture: Sakurambo (Own work) [Public domain]
  • 46.
    Tangent 1: SpecialRelativity A B C
  • 47.
    Tangent 1: SpecialRelativity A B C A, B, C
  • 48.
    Tangent 1: SpecialRelativity A B C A, B, C C, B, A
  • 49.
    Tangent 1: SpecialRelativity Observed order depends on viewer's frame of reference A B C A, B, C C, B, A
  • 50.
    No single “correct”timeline Special Relativity Observed order of events depends on frame of reference
  • 51.
    No single “correct”timeline Special Relativity Observed order of events depends on frame of reference Multithreaded Code Observed order of events depends on thread
  • 52.
    Memory Model Definition 2 Clarifywhat multithreaded behavior developers may depend on
  • 53.
    Memory Model Definition 2 Clarifywhat multithreaded behavior developers may depend on Limits what types of optimizations the runtime may do
  • 54.
  • 55.
    Java Memory Model(JMM) Write once, run anywhere 1995 Part of the formal language specification Happened-before picture: Peter Campbell [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 4.0-3.0-2.5-2.0-1.0 (http://creativecommons.org/licenses/by-sa/4.0-3.0-2.5-2.0-1.0)]
  • 56.
  • 57.
    Leslie Lamport LaTex happened-before picture: LeslieLamport [GFDL (http://en.wikipedia.org/wiki/GFDL]
  • 58.
    happened-before void hoge5() { a= 1; b = 2; c = 3; d = 4; e = 5; a = a + 1; }
  • 59.
    happened-before void hoge4() { data= 42; ready = true; } void hoge3() { while (!ready) {}; assert data == 42; }
  • 60.
    happened-before void hoge4() { data= 42; ready = true; } void hoge3() { while (!ready) {}; assert data == 42; }
  • 61.
    happened-before void synchronized hoge4(){ data = 42; ready = true; } void synchronized hoge3() { while (!ready) {}; assert data == 42; } Warning: if hoge3 is executed first, the above code will deadlock
  • 62.
    happened-before void synchronized hoge4() { data= 42; ready = true; } void synchronized hoge3() { while (!ready) {}; assert data == 42; } Warning: if hoge3 is executed first, the above code will deadlock
  • 63.
  • 64.
  • 65.
    Original JMM Keywords synchronized mutualexclusion happened-before volatile Visibility
  • 66.
    Problems with theOriginal JMM volatile does not establish a happened-before relationship final values can change Many important runtime optimization were not allowed
  • 67.
    Doug Lea Author ofthe Java Multithreaded bible Introduced his own OSS high- level multithreaded library
  • 68.
    Java SE 5.0 ModernJMM introduced Lea’s library added to official JDK picture: Zvi Roger [CC BY 3.0 (http://creativecommons.org/licenses/by/3.0)]
  • 69.
    Modern JMM JSR-133 Fixed shortcomingsin original JMM volatile does establish happens-before final values will never change
  • 70.
    Modern JMM Keywords synchronized mutualexclusion happened-before volatile visibility happened-before final immutability
  • 71.
    JSR-133 の volatile voidhoge4() { data = 42; ready = true; } void hoge3() { while (!ready) {}; assert data == 42; } Warning: if hoge3 is executed first, the above code will deadlock volatile boolean ready = false;
  • 72.
    volatile != atomic volatileint id = 0; int incID() { return id++; }
  • 73.
    volatile != atomic volatileint id = 0; int incID() { return id++; } reg = [id] reg++ [id] = reg
  • 74.
    volatile != atomic volatileint id = 0; synchronized int incID() { return id++; }
  • 75.
    64-bit updates arenot guaranteed atomic • Reads and Writes to long and double values may not happen atomically • Possible to read a mix of two different writes Copyright © 2019 Oracle and/or its affiliates. Old value MSB New value LSB
  • 76.
    happened-before Monitor (acquisition /release) Volatile (read / write) final “freeze” (constructor) JNI System.out.println() Input / Output thread start()/join() operations on j.u.concurrent collections
  • 77.
  • 78.
  • 79.
  • 80.
    Functional Programming (JDK8) Lambda Forms Stream API λ
  • 81.
    Var Handles • Lower-levelthan volatile / final • Allows a value to be volatile only when we want it to be • Explicate fence and acquire / release semantics • Added in JDK 9 to replace several use cases previously only supported with sun.misc.Unsafe Copyright © 2019 Oracle and/or its affiliates.
  • 82.
  • 83.
    Tangent 2: HSDIS(HotSpot Disassembler) Lets us see code generated by JIT Requires a disassembler plugin GNU binutils-based plugin base-hsdis Command line options +PrintAssembly +CompileCommand=print,*MyClass.myMethod
  • 84.
  • 85.
  • 86.
    ARM Assembly CrashCourse Op Target Source
  • 87.
    ARM Assembly CrashCourse MOV r02 #42
  • 88.
    ARM Assembly CrashCourse MOV r02 #42 r02 = 42
  • 89.
    ARM Assembly CrashCourse Op Target Source
  • 90.
    ARM Assembly CrashCourse Op Target Source Exception STR Source Target
  • 91.
    ARM Assembly CrashCourse MOV Copies registers MOV r02 r03 Writes Literals MOV r02 #42
  • 92.
    ARM Assembly CrashCourse LDx Loads data from memory to a register ldr r03, [r06] r03 = *r06
  • 93.
    ARM Assembly CrashCourse CMP / BEQ Compare and branch if equal cmp r0, #0 beq 0x74178d08 if (r0 == 0) goto 0x74178d08
  • 94.
    ARM Assembly CrashCourse DMB Data Memory Barrier dmb st dmb sy
  • 95.
  • 96.
    Safe Points Methods proactivelypoll JVM makes page unreadable to stop the world movw ip, #45056 ; 0xb000 movt ip, #30461 ; 0x76fd ldr ip, [ip] ; {poll_return}
  • 97.
    Long Value static longval = 0; public static void main(String[] args) { new Thread(() -> { while(true) val = -1L; } ).start(); new Thread(() -> { while(true) val = 0L; } ).start(); while (true) { long temp = val; if ( temp != -1 && temp != 0 ) { System.out.println("temp (DEC): " + temp); System.out.println("temp (BIN): " + Long.toBinaryString(temp)); System.exit(-1); } } }
  • 98.
    Object Initialization public classObjInit { static ObjInit globalRef = new ObjInit(); long number; public ObjInit() { number = 42; }
  • 99.
    Object Initialization public staticvoid main(String[] args) { new Thread(() -> { while(true) { long temp = globalRef.number; if (temp != 42) { System.out.println(temp); System.exit(-1); } } } ).start(); new Thread(() -> { while(true) globalRef = new ObjInit(); } ).start(); }}
  • 100.
    public class Loopextends Thread { static boolean done = false; public static void main(String[] args) { Thread childThread = new Loop(); childThread.start(); System.out.println("Starting loop"); spinWait(); System.out.println("Exited loop"); } private static void spinWait() { while (!done) ; } public void run() { try { Thread.sleep(5 * 1000); } catch (Exception e) {} done = true; } } // class Loop Loop
  • 101.
  • 102.
    JEP-188/JMM9 Not delivered withJDK 9 (JMM9 != JDK 9) JVM-level specification Compatibility with C11/C++11 Cover new features added since JDK 5 (e.g. AtomicX.weakCompareAndSet())
  • 103.
  • 104.
  • 105.
    Code against thespecification Intermittent bugs are common Behavior changes with JRE / platform Stuff to avoid synchronized (new Object()) { } Randomly adding volatile declarations until it magically starts working
  • 106.
    Testing As close toproduction environment as possible Same hardware Same JRE (including version) Same settings
  • 107.
    Testing As much varietyas possible Various hardware Various JREs (including version) Various settings
  • 108.
    Java Concurrency inPractice Java Concurrency Bible Covers JSR-133 / JSR-166
  • 109.
    Summary Avoid low-level APIs Codeagainst the standard, not the implementation Testing is always indispensible Must read Java Concurrency in Practice (JCiP)
  • 110.
  • 111.
    [ JSR 133(Java Memory Model) FAQ ] https://www.cs.umd.edu/~pugh/java/ memoryModel/jsr-133-faq.html [ Java Concurrency in Practice ] http://jcip.net/ [ Concurrent Programming in Java ] http://gee.cs.oswego.edu/dl/cpj/ [ The JSR-133 Cookbook for Compiler Writers ] http://gee.cs.oswego.edu/dl/jmm/cook book.html [ PrintAssembly ] https://wiki.openjdk.java.net/display/H otSpot/PrintAssembly [ BASIC DISASSEMBLER PLUGIN FOR HOTSPOT DOWNLOADS ] https://kenai.com/projects/base- hsdis/downloads References
  • 112.
    Session Survey Help usmake the content even better. Please complete the session survey in the Mobile App. Copyright © 2019 Oracle and/or its affiliates.
  • 113.
    The preceding isintended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2019 Oracle and/or its affiliates.