SlideShare uma empresa Scribd logo
1 de 71
Baixar para ler offline
CONCURRENCY
CONCEPTS IN JAVA
DOUGLAS Q. HAWKINS
LEAD JIT DEVELOPER
AZUL SYSTEMS
@dougqh
dougqh@gmail.com
TOPICS
NOT ABOUT
PARALLEL FORK JOIN
AKKA
EXECUTORS & FUTURES
…
CORE MEMORY MODEL
ATOMICITY
ORDERING
VISIBILITY
HISTORY & FUTURE OF THE MEMORY MODEL
TOPICS
WHO’S READ THIS?
YOU SHOULD READ THE FINE PRINT.
TLDR: “AS IF”
AS IF THERE’S ONE THREAD,
UNLESS YOU SAY OTHERWISE.
The behavior of threads, particularly
when not correctly synchronized, can
be confusing and counterintuitive.
“
“
Java 8 Language Specification
§ 17.4 pp 631
Immutable objects have a very compelling
list of positive qualities. Without question,
they are among the simplest and most robust
kinds of classes you can possibly build. When
you create immutable classes, entire
categories of problems simply disappear.
“ “
www.javapractices.com
ATOMICITYWHAT OPERATIONS ARE INDIVISIBLE?
SUCCINCT != ATOMIC
sharedX = 2L;
sharedX = 2L sharedX = -1L
set_hi sharedX, 0000 0000
set_lo sharedX, 0000 0002
set_hi sharedX, ffff ffff
set_lo sharedX, ffff ffff
thread 1 thread 2
JLS8 § 17.7 pp 658
SUCCINCT != ATOMIC
sharedX += 1;
localX = sharedX;
localX = localX + 1;
sharedX = localX;
SUCCINCT != ATOMIC
Point sharedPoint = new Point(x, y);
local1 = calloc(sizeof(Point));
local1.<init>(x, y);
Object.<init>();
this.x = x;
this.y = y;
sharedPoint = local1;
VISIBILITYWHAT CAN OTHER THREADS SEE?
NO GARBAGE VALUES
NO OUT OF “THIN AIR” VALUES
WILL SEE A ZERO-ISH VALUE
OR
AN ASSIGNED VALUE
NO *COMPLETELY* GARBAGE VALUES
TWO SEPARATE HALVES OF LONG OR DOUBLE
BUT
BOTH HALVES ARE ZERO OR ASSIGNED
ONLY ASSIGNED VALUES FOR FINALS
sharedPoint = new Point(x, y);
class Point {
final int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
*
*After constructor return
JLS8 § 17.5 pp 652
NOT *ALL* VALUES ARE STORED
sharedX = 20;
sharedX = 40;
print(sharedX);
Dead Store
DATA DEPENDENCE
sharedX = 20;
sharedX = 40;
print(sharedX);
Dead Store
Data
Dependence
DATA DEPENDENCE
sharedX = 20;
sharedX = 40;
print(40);
Data
Dependence
Propagate
Data
Dead Stores
OKAY.
NOT *ALL* VALUES ARE STORED
sharedSum = 0;
for ( int x : array ) {
sharedSum += x;
}
INTERMEDIATE VALUES OPTIONAL
localSum = 0;
for ( int x : array ) {
localSum += x;
}
sharedSum = localSum;
WHAT?
THREAD PUBLISHING
METHOD PUBLISHES?
Thread.sleep NO
Thread.yield NO
Thread.join YES
Thread.isAlive YES*
* If Thread.isAlive returns false
JLS8 § 17.4 pp 636
NOT *ALL* VALUES ARE READ
xSquared = sharedX * sharedX
Can xSquared be 30?
local1 = sharedX
local2 = sharedX
xSquared = local1 * local2
NOT *ALL* VALUES ARE READ
Can xSquared be 30?
local1 = sharedX
local2 = sharedX
xSquared = local1 * local2
thread 1 thread 2
sharedX = 5;
local1 = sharedX; (5)
sharedX = 6;
local2 = sharedX; (6)
xSquared =
local1 * local2;
(30)
NOT *ALL* VALUES ARE READ
xSquared = sharedX * sharedX
local1 = sharedX
local2 = sharedX
xSquared = local1 * local2
local1 = sharedX
xSquared = local1 * local1
Redundant Load
GREAT!
IMPORTANT OPTIMIZATION
for ( int x: array ) {
… x …
}
for ( int i = 0; i < this.array.length; ++i ) {
… this.array[i] …
}
Object[] local = this.array;
for ( int i = 0; i < local.length; ++i ) {
… local[i] …
}
EXCELLENT!20+% FASTER
MAYBE NOT…
while ( !done ); local1 = !done;
while ( local1 );
Load False &
Loop Forever
To some programmers, this behavior
may seem broken. However, it should
be noted that this code is improperly
synchronized.
“
“
Java 8 Language Specification
§ 17.4 pp 638
MEMORY COHERENCE
Coherence is a guarantee that a
thread cannot see an old value for
the same memory location after
seeing a newer value.
TIME PARADOX
// sharedPoint1 might equal
// sharedPoint2
int i = sharedPoint1.x;
// another thread can change x
int j = sharedPoint2.x;
// allow old value or
// cannot optimize
int k = sharedPoint3.x;
Point
x
y
100
100
125
sharedPoint1
sharedPoint2
JLS8 § 17.4-C pp 638
The semantics of the Java programming
language allow compilers and micro-
processors to perform optimizations that
can interact with incorrectly synchronized
code in ways that can produce behaviors
that seem paradoxical.
“ “
Java 8 Language Specification
§ 17.4 pp 637
ORDERINGWHAT ORDER DOES IT RUN IN?
“PROGRAM ORDER”
sharedX = 2
sharedY = 3
if ( sharedX > 0 ) {
print(sharedX);
}
Control
Data
Data
DATA + CONTROL DEPENDENCE
DATA CONTROL DEPENDENCE+
sharedX = 2
start
end
print(x)
if ( sharedX > 0 )
true false
sharedY = 3
https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake
FETCH
RENAME & ALLOCATE
DECODE
ALLOCATION QUEUE
SCHEDULERS
ALU
VECT ALU
VECT SHIFT
VECT ADD
VECT MUL
FMA
DIV
BRANCH
ALU
FAST LEA
VECT ALU
VECT SHIFT
VECT ADD
VECT MUL
FMA
SLOW INT
SLOW LEA
ALU
FAST LEA
VECT ALU
VECT SHUFFLE
ALU & SHIFT
BRANCH
AGU
LOAD DATA
AGU
LOAD DATA
STORE DATA AGU
INTEL KABY LAKE
LOAD
BUFFER
STORE
BUFFER
INTEL KABY LAKE
https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake
FETCH
RENAME & ALLOCATE
DECODE
ALLOCATION QUEUE
SCHEDULERS
ALU
VECT ALU
VECT SHIFT
VECT ADD
VECT MUL
FMA
DIV
BRANCH
ALU
FAST LEA
VECT ALU
VECT SHIFT
VECT ADD
VECT MUL
FMA
SLOW INT
SLOW LEA
ALU
FAST LEA
VECT ALU
VECT SHUFFLE
ALU & SHIFT
BRANCH
AGU
LOAD DATA
AGU
LOAD DATA
STORE DATA AGU
LOAD
BUFFER
STORE
BUFFER
add reg0, 1 add reg1, 2
COOL.
BUT COMPLICATES
EVERYTHING.
STORE SOONER
local1 = calloc(sizeof(Point));
local1.<init>(…);
…
sharedPoint = local1;
sharedFoo = new Foo(…);
Data
Data
FREE TO REORDER
local1 = calloc(sizeof(Point));
sharedPoint = local1;
local1.<init>(…);
sharedFoo = new Foo(…);
Data
Data
Reordered!
*BROKEN* DOUBLE CHECKED LOCKING
static Singleton instance() {
if ( sharedInstance == null ) {
synchronized ( Singleton.class ) {
if ( sharedInstance == null ) {
sharedInstance = new Singleton();
}
}
}
return sharedInstance;
}
static Singleton instance() {
if ( sharedInstance == null ) {
synchronized ( Singleton.class ) {
if ( sharedInstance == null ) {
local = calloc(sizeof(Singleton));
sharedInstance = local;
local.<init>();
}
}
}
return sharedInstance;
}
sharedInstance is non-null,
but constructor hasn’t run.
PRODUCER CONSUMER
...
sharedData = ...;
sharedDone = true;
...
sharedDone = true;
sharedData = ...;
while ( !sharedDone );
print(sharedData);
Reorder!
AGAIN BLAME
HARDWARE.
RISC / ARM CISC / x86
Loads After Loads YES YES
Loads After Stores YES YES
Stores After Stores YES NO
Stores After Loads YES YES
...
sharedData = …;
store_store_fence();
sharedDone = true;
while ( !sharedDone ) {
load_load_fence();
}
print(sharedData);
TO STOP REORDERING, USE A *FENCE*
PRODUCER CONSUMER
BLAME JAVA,
TOO.
RISC / ARM CISC / x86 Java
Loads After Loads YES YES YES
Loads After Stores YES YES YES
Stores After Stores YES NO YES
Stores After Loads YES YES YES
HOW DO YOU TELL
JAVA TO NOT REORDER?
SYNCHRONIZATION ACTIONS
VOLATILE
SYNCHRONIZED
FINAL / FREEZE
UNSAFE
ATOMICS
VAR HANDLES
FINAL & FREEZE
local1 = calloc(sizeof(Point));
local1.<init>(x, y);
Object.<init>();
this.x = x;
this.y = y;
freeze();
sharedPoint = local1;
Point sharedPoint = new Point(x, y);
FINAL & FREEZE
local1 = calloc(sizeof(Point));
local1.<init>(x, y);
Object.<init>();
this.x = x;
this.y = y;
OtherThread.see(this);
freeze();
sharedPoint = local1;
Point sharedPoint = new Point(x, y);
Free to Reorder!
VOLATILE
PRE-JAVA 5 JUST ATOMICITY FOR CATEGORY 2 TYPES:
WRITE “SYNCHRONIZES WITH”
*ALL* SUBSEQUENT READS
WRITE “HAPPENS BEFORE”
*ALL* SUBSEQUENT READS
JLS8 § 17.4.4 & 17.4.5 pp 642 & 643
VOLATILE
...
volatileData = …;
volatileDone = true;
while ( !volatileDone ) {
}
print(volatileData);
PRODUCER CONSUMER
ALSO FIXES DOUBLE CHECKED LOCKING
static Singleton instance() {
if ( sharedInstance == null ) {
synchronized ( Singleton.class ) {
if ( sharedInstance == null ) {
local = calloc(sizeof(Singleton));
local.<init>();
sharedInstance = local;
}
}
}
return sharedInstance;
}
RIGHT WAY TO DO LAZY SINGLETON IN JAVA
static Singleton instance() {
return Holder.INSTANCE;
}
static class Holder {
static final class Singleton INSTANCE = new Singleton();
}
CLASS INITIALIZATION IS ALREADY LAZY.
SUCCINCT *STILL* != ATOMIC
volatileX += 1;
localX = sharedX;
localX = localX + 1;
sharedX = localX;
fullFence fullFence
loadLoadFence
storeStoreFence
acquireFence
releaseFence
NOT *ENTIRELY* ACADEMIC
UNSAFE VARHANDLES
SYNCHRONIZED
synchronized (Foo.class) {
counter += 1;
}
WAIT & NOTIFY
synchronized (lock) {
sharedData = …;
sharedDone = true;
lock.notify();
}
synchronized (lock) {
while ( !sharedDone ) {
lock.wait();
}
print(sharedData);
}
PRODUCER CONSUMER
DOESN’T PRESERVE ORDER
synchronized (lock) {
sharedData = …;
sharedDone = true;
lock.notify();
}
synchronized (lock) {
while ( !sharedDone ) {
lock.wait();
}
print(sharedData);
}
PRODUCER CONSUMER
synchronized (lock) {
sharedDone = true;
sharedData = …;
lock.notify();
}
Reorder!
SPURIOUS NOTIFICATIONS
synchronized (lock) {
while ( !sharedDone ) {
lock.wait();
}
print(sharedData);
}
*CORRECT* CONSUMER
synchronized (lock) {
if ( !sharedDone ) {
lock.wait();
}
print(sharedData);
}
*INCORRECT* CONSUMER
LOCK COARSENING
synchronized ( buffer ) {
buffer.add(x);
}
foo = bar;
synchronized ( buffer ) {
buffer.add(y);
}
https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/
synchronized ( buffer ) {
buffer.add(x);
foo = bar;
buffer.add(y);
}
COMPARE & SWAP
AtomicInteger atomic = new AtomicInteger(0);
atomic.getAndIncrement();
boolean applied = false;
do {
int value = sharedVar.get();
applied = sharedVar.compareAndSet(
value, value + 1);
} while ( ! applied );
JAVA.UTIL.CONCURRENT
ConcurrentLinkedQueue
ConcurrentHashMap
A
B
C
D
LinkedTransferQueue
head tail
CONCURRENCY CAN SEEM...
BROKEN
COUNTERINTUITIVE
PARADOXICAL
DESPITE THE RULES
Immutable objects have a very compelling
list of positive qualities. Without question,
they are among the simplest and most robust
kinds of classes you can possibly build. When
you create immutable classes, entire
categories of problems simply disappear.
“ “
www.javapractices.com
REFERENCES
JAVA CURRENCY IN PRACTICE
Brian Goetz et al
JAVA MEMORY MODEL PRAGMATICS
Aleksey Shipilëv
http://virtualjug.com/java-memory-model-pragmatics/
CLOSE ENCOUNTERS OF THE JMM KIND
Aleksey Shipilëv
https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/
HISTORY
JAVA’S MEMORY MODEL IS FATALLY FLAWED
Bill Pugh
http://www.cs.umd.edu/~pugh/java/broken.pdf
Bill Pugh
FIXING JAVA’S MEMORY MODEL
http://www.cs.umd.edu/~pugh/jmm.pdf
AND OF COURSE

Mais conteúdo relacionado

Mais procurados

.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
Jussi Pohjolainen
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
julien.ponge
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
julien.ponge
 

Mais procurados (20)

Java_practical_handbook
Java_practical_handbookJava_practical_handbook
Java_practical_handbook
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
Scala to assembly
Scala to assemblyScala to assembly
Scala to assembly
 
Java practical
Java practicalJava practical
Java practical
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Java PRACTICAL file
Java PRACTICAL fileJava PRACTICAL file
Java PRACTICAL file
 
Java 7 LavaJUG
Java 7 LavaJUGJava 7 LavaJUG
Java 7 LavaJUG
 
Kotlin 101 for Java Developers
Kotlin 101 for Java DevelopersKotlin 101 for Java Developers
Kotlin 101 for Java Developers
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
Kotlin meets Gadsu
Kotlin meets GadsuKotlin meets Gadsu
Kotlin meets Gadsu
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
bluespec talk
bluespec talkbluespec talk
bluespec talk
 
Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.Final JAVA Practical of BCA SEM-5.
Final JAVA Practical of BCA SEM-5.
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Java Generics - by Example
Java Generics - by ExampleJava Generics - by Example
Java Generics - by Example
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
 

Semelhante a Concurrency Concepts in Java

AST Transformations
AST TransformationsAST Transformations
AST Transformations
HamletDRC
 

Semelhante a Concurrency Concepts in Java (20)

Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
 
Scala in Practice
Scala in PracticeScala in Practice
Scala in Practice
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with Clojure
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017
 
Jasmine BDD for Javascript
Jasmine BDD for JavascriptJasmine BDD for Javascript
Jasmine BDD for Javascript
 
Getting started with ES6 : Future of javascript
Getting started with ES6 : Future of javascriptGetting started with ES6 : Future of javascript
Getting started with ES6 : Future of javascript
 
Red Hat Agile integration Workshop Labs
Red Hat Agile integration Workshop LabsRed Hat Agile integration Workshop Labs
Red Hat Agile integration Workshop Labs
 
Elixir - GDG - Nantes
Elixir - GDG - NantesElixir - GDG - Nantes
Elixir - GDG - Nantes
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
 
Play framework
Play frameworkPlay framework
Play framework
 
Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at...
 Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at... Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at...
Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at...
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
Java 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from Oredev
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
React, Redux, ES2015 by Max Petruck
React, Redux, ES2015 by Max PetruckReact, Redux, ES2015 by Max Petruck
React, Redux, ES2015 by Max Petruck
 
JRuby e DSL
JRuby e DSLJRuby e DSL
JRuby e DSL
 
Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)Kotlin: forse è la volta buona (Trento)
Kotlin: forse è la volta buona (Trento)
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 

Mais de Doug Hawkins

Mais de Doug Hawkins (8)

ReadyNow: Azul's Unconventional "AOT"
ReadyNow: Azul's Unconventional "AOT"ReadyNow: Azul's Unconventional "AOT"
ReadyNow: Azul's Unconventional "AOT"
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Understanding Garbage Collection
Understanding Garbage CollectionUnderstanding Garbage Collection
Understanding Garbage Collection
 
JVM Internals - NHJUG Jan 2012
JVM Internals - NHJUG Jan 2012JVM Internals - NHJUG Jan 2012
JVM Internals - NHJUG Jan 2012
 
Inside Android's Dalvik VM - NEJUG Nov 2011
Inside Android's Dalvik VM - NEJUG Nov 2011Inside Android's Dalvik VM - NEJUG Nov 2011
Inside Android's Dalvik VM - NEJUG Nov 2011
 
JVM Internals - NEJUG Nov 2010
JVM Internals - NEJUG Nov 2010JVM Internals - NEJUG Nov 2010
JVM Internals - NEJUG Nov 2010
 
Introduction to Class File Format & Byte Code
Introduction to Class File Format & Byte CodeIntroduction to Class File Format & Byte Code
Introduction to Class File Format & Byte Code
 
JVM Internals - Garbage Collection & Runtime Optimizations
JVM Internals - Garbage Collection & Runtime OptimizationsJVM Internals - Garbage Collection & Runtime Optimizations
JVM Internals - Garbage Collection & Runtime Optimizations
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 

Concurrency Concepts in Java

  • 1. CONCURRENCY CONCEPTS IN JAVA DOUGLAS Q. HAWKINS LEAD JIT DEVELOPER AZUL SYSTEMS @dougqh dougqh@gmail.com
  • 2. TOPICS NOT ABOUT PARALLEL FORK JOIN AKKA EXECUTORS & FUTURES …
  • 3. CORE MEMORY MODEL ATOMICITY ORDERING VISIBILITY HISTORY & FUTURE OF THE MEMORY MODEL TOPICS
  • 5. YOU SHOULD READ THE FINE PRINT. TLDR: “AS IF” AS IF THERE’S ONE THREAD, UNLESS YOU SAY OTHERWISE.
  • 6. The behavior of threads, particularly when not correctly synchronized, can be confusing and counterintuitive. “ “ Java 8 Language Specification § 17.4 pp 631
  • 7. Immutable objects have a very compelling list of positive qualities. Without question, they are among the simplest and most robust kinds of classes you can possibly build. When you create immutable classes, entire categories of problems simply disappear. “ “ www.javapractices.com
  • 9. SUCCINCT != ATOMIC sharedX = 2L; sharedX = 2L sharedX = -1L set_hi sharedX, 0000 0000 set_lo sharedX, 0000 0002 set_hi sharedX, ffff ffff set_lo sharedX, ffff ffff thread 1 thread 2 JLS8 § 17.7 pp 658
  • 10. SUCCINCT != ATOMIC sharedX += 1; localX = sharedX; localX = localX + 1; sharedX = localX;
  • 11. SUCCINCT != ATOMIC Point sharedPoint = new Point(x, y); local1 = calloc(sizeof(Point)); local1.<init>(x, y); Object.<init>(); this.x = x; this.y = y; sharedPoint = local1;
  • 12. VISIBILITYWHAT CAN OTHER THREADS SEE?
  • 13. NO GARBAGE VALUES NO OUT OF “THIN AIR” VALUES WILL SEE A ZERO-ISH VALUE OR AN ASSIGNED VALUE
  • 14. NO *COMPLETELY* GARBAGE VALUES TWO SEPARATE HALVES OF LONG OR DOUBLE BUT BOTH HALVES ARE ZERO OR ASSIGNED
  • 15. ONLY ASSIGNED VALUES FOR FINALS sharedPoint = new Point(x, y); class Point { final int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } * *After constructor return JLS8 § 17.5 pp 652
  • 16. NOT *ALL* VALUES ARE STORED sharedX = 20; sharedX = 40; print(sharedX); Dead Store
  • 17. DATA DEPENDENCE sharedX = 20; sharedX = 40; print(sharedX); Dead Store Data Dependence
  • 18. DATA DEPENDENCE sharedX = 20; sharedX = 40; print(40); Data Dependence Propagate Data Dead Stores
  • 19. OKAY.
  • 20. NOT *ALL* VALUES ARE STORED sharedSum = 0; for ( int x : array ) { sharedSum += x; } INTERMEDIATE VALUES OPTIONAL localSum = 0; for ( int x : array ) { localSum += x; } sharedSum = localSum;
  • 21. WHAT?
  • 22. THREAD PUBLISHING METHOD PUBLISHES? Thread.sleep NO Thread.yield NO Thread.join YES Thread.isAlive YES* * If Thread.isAlive returns false JLS8 § 17.4 pp 636
  • 23. NOT *ALL* VALUES ARE READ xSquared = sharedX * sharedX Can xSquared be 30? local1 = sharedX local2 = sharedX xSquared = local1 * local2
  • 24. NOT *ALL* VALUES ARE READ Can xSquared be 30? local1 = sharedX local2 = sharedX xSquared = local1 * local2 thread 1 thread 2 sharedX = 5; local1 = sharedX; (5) sharedX = 6; local2 = sharedX; (6) xSquared = local1 * local2; (30)
  • 25. NOT *ALL* VALUES ARE READ xSquared = sharedX * sharedX local1 = sharedX local2 = sharedX xSquared = local1 * local2 local1 = sharedX xSquared = local1 * local1 Redundant Load
  • 27. IMPORTANT OPTIMIZATION for ( int x: array ) { … x … } for ( int i = 0; i < this.array.length; ++i ) { … this.array[i] … } Object[] local = this.array; for ( int i = 0; i < local.length; ++i ) { … local[i] … }
  • 29. MAYBE NOT… while ( !done ); local1 = !done; while ( local1 ); Load False & Loop Forever
  • 30. To some programmers, this behavior may seem broken. However, it should be noted that this code is improperly synchronized. “ “ Java 8 Language Specification § 17.4 pp 638
  • 31. MEMORY COHERENCE Coherence is a guarantee that a thread cannot see an old value for the same memory location after seeing a newer value.
  • 32. TIME PARADOX // sharedPoint1 might equal // sharedPoint2 int i = sharedPoint1.x; // another thread can change x int j = sharedPoint2.x; // allow old value or // cannot optimize int k = sharedPoint3.x; Point x y 100 100 125 sharedPoint1 sharedPoint2 JLS8 § 17.4-C pp 638
  • 33. The semantics of the Java programming language allow compilers and micro- processors to perform optimizations that can interact with incorrectly synchronized code in ways that can produce behaviors that seem paradoxical. “ “ Java 8 Language Specification § 17.4 pp 637
  • 35. “PROGRAM ORDER” sharedX = 2 sharedY = 3 if ( sharedX > 0 ) { print(sharedX); } Control Data Data DATA + CONTROL DEPENDENCE
  • 36. DATA CONTROL DEPENDENCE+ sharedX = 2 start end print(x) if ( sharedX > 0 ) true false sharedY = 3
  • 37. https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake FETCH RENAME & ALLOCATE DECODE ALLOCATION QUEUE SCHEDULERS ALU VECT ALU VECT SHIFT VECT ADD VECT MUL FMA DIV BRANCH ALU FAST LEA VECT ALU VECT SHIFT VECT ADD VECT MUL FMA SLOW INT SLOW LEA ALU FAST LEA VECT ALU VECT SHUFFLE ALU & SHIFT BRANCH AGU LOAD DATA AGU LOAD DATA STORE DATA AGU INTEL KABY LAKE LOAD BUFFER STORE BUFFER
  • 38. INTEL KABY LAKE https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake FETCH RENAME & ALLOCATE DECODE ALLOCATION QUEUE SCHEDULERS ALU VECT ALU VECT SHIFT VECT ADD VECT MUL FMA DIV BRANCH ALU FAST LEA VECT ALU VECT SHIFT VECT ADD VECT MUL FMA SLOW INT SLOW LEA ALU FAST LEA VECT ALU VECT SHUFFLE ALU & SHIFT BRANCH AGU LOAD DATA AGU LOAD DATA STORE DATA AGU LOAD BUFFER STORE BUFFER add reg0, 1 add reg1, 2
  • 39. COOL.
  • 41. STORE SOONER local1 = calloc(sizeof(Point)); local1.<init>(…); … sharedPoint = local1; sharedFoo = new Foo(…); Data Data
  • 42. FREE TO REORDER local1 = calloc(sizeof(Point)); sharedPoint = local1; local1.<init>(…); sharedFoo = new Foo(…); Data Data Reordered!
  • 43. *BROKEN* DOUBLE CHECKED LOCKING static Singleton instance() { if ( sharedInstance == null ) { synchronized ( Singleton.class ) { if ( sharedInstance == null ) { sharedInstance = new Singleton(); } } } return sharedInstance; } static Singleton instance() { if ( sharedInstance == null ) { synchronized ( Singleton.class ) { if ( sharedInstance == null ) { local = calloc(sizeof(Singleton)); sharedInstance = local; local.<init>(); } } } return sharedInstance; } sharedInstance is non-null, but constructor hasn’t run.
  • 44. PRODUCER CONSUMER ... sharedData = ...; sharedDone = true; ... sharedDone = true; sharedData = ...; while ( !sharedDone ); print(sharedData); Reorder!
  • 46. RISC / ARM CISC / x86 Loads After Loads YES YES Loads After Stores YES YES Stores After Stores YES NO Stores After Loads YES YES
  • 47. ... sharedData = …; store_store_fence(); sharedDone = true; while ( !sharedDone ) { load_load_fence(); } print(sharedData); TO STOP REORDERING, USE A *FENCE* PRODUCER CONSUMER
  • 49. RISC / ARM CISC / x86 Java Loads After Loads YES YES YES Loads After Stores YES YES YES Stores After Stores YES NO YES Stores After Loads YES YES YES
  • 50. HOW DO YOU TELL JAVA TO NOT REORDER?
  • 51. SYNCHRONIZATION ACTIONS VOLATILE SYNCHRONIZED FINAL / FREEZE UNSAFE ATOMICS VAR HANDLES
  • 52. FINAL & FREEZE local1 = calloc(sizeof(Point)); local1.<init>(x, y); Object.<init>(); this.x = x; this.y = y; freeze(); sharedPoint = local1; Point sharedPoint = new Point(x, y);
  • 53. FINAL & FREEZE local1 = calloc(sizeof(Point)); local1.<init>(x, y); Object.<init>(); this.x = x; this.y = y; OtherThread.see(this); freeze(); sharedPoint = local1; Point sharedPoint = new Point(x, y); Free to Reorder!
  • 54. VOLATILE PRE-JAVA 5 JUST ATOMICITY FOR CATEGORY 2 TYPES: WRITE “SYNCHRONIZES WITH” *ALL* SUBSEQUENT READS WRITE “HAPPENS BEFORE” *ALL* SUBSEQUENT READS JLS8 § 17.4.4 & 17.4.5 pp 642 & 643
  • 55. VOLATILE ... volatileData = …; volatileDone = true; while ( !volatileDone ) { } print(volatileData); PRODUCER CONSUMER
  • 56. ALSO FIXES DOUBLE CHECKED LOCKING static Singleton instance() { if ( sharedInstance == null ) { synchronized ( Singleton.class ) { if ( sharedInstance == null ) { local = calloc(sizeof(Singleton)); local.<init>(); sharedInstance = local; } } } return sharedInstance; }
  • 57. RIGHT WAY TO DO LAZY SINGLETON IN JAVA static Singleton instance() { return Holder.INSTANCE; } static class Holder { static final class Singleton INSTANCE = new Singleton(); } CLASS INITIALIZATION IS ALREADY LAZY.
  • 58. SUCCINCT *STILL* != ATOMIC volatileX += 1; localX = sharedX; localX = localX + 1; sharedX = localX;
  • 61. WAIT & NOTIFY synchronized (lock) { sharedData = …; sharedDone = true; lock.notify(); } synchronized (lock) { while ( !sharedDone ) { lock.wait(); } print(sharedData); } PRODUCER CONSUMER
  • 62. DOESN’T PRESERVE ORDER synchronized (lock) { sharedData = …; sharedDone = true; lock.notify(); } synchronized (lock) { while ( !sharedDone ) { lock.wait(); } print(sharedData); } PRODUCER CONSUMER synchronized (lock) { sharedDone = true; sharedData = …; lock.notify(); } Reorder!
  • 63. SPURIOUS NOTIFICATIONS synchronized (lock) { while ( !sharedDone ) { lock.wait(); } print(sharedData); } *CORRECT* CONSUMER synchronized (lock) { if ( !sharedDone ) { lock.wait(); } print(sharedData); } *INCORRECT* CONSUMER
  • 64. LOCK COARSENING synchronized ( buffer ) { buffer.add(x); } foo = bar; synchronized ( buffer ) { buffer.add(y); } https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/ synchronized ( buffer ) { buffer.add(x); foo = bar; buffer.add(y); }
  • 65. COMPARE & SWAP AtomicInteger atomic = new AtomicInteger(0); atomic.getAndIncrement(); boolean applied = false; do { int value = sharedVar.get(); applied = sharedVar.compareAndSet( value, value + 1); } while ( ! applied );
  • 68. Immutable objects have a very compelling list of positive qualities. Without question, they are among the simplest and most robust kinds of classes you can possibly build. When you create immutable classes, entire categories of problems simply disappear. “ “ www.javapractices.com
  • 69. REFERENCES JAVA CURRENCY IN PRACTICE Brian Goetz et al JAVA MEMORY MODEL PRAGMATICS Aleksey Shipilëv http://virtualjug.com/java-memory-model-pragmatics/ CLOSE ENCOUNTERS OF THE JMM KIND Aleksey Shipilëv https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/
  • 70. HISTORY JAVA’S MEMORY MODEL IS FATALLY FLAWED Bill Pugh http://www.cs.umd.edu/~pugh/java/broken.pdf Bill Pugh FIXING JAVA’S MEMORY MODEL http://www.cs.umd.edu/~pugh/jmm.pdf