Semantics of Semantics of Multithreaded JavaMultithreaded Java
Jeremy Manson and William PughJeremy Manson and William Pugh
Background MaterialBackground Material
Jack NewtonUniversity of Alberta
Semantics of Multithreaded Java 2
OverviewOverview
Multithreaded Programming in JavaMultithreaded Programming in Java Memory Consistency ModelsMemory Consistency Models Java Memory ModelJava Memory Model Problems with the Java Memory ModelProblems with the Java Memory Model
Semantics of Multithreaded Java 3
Multithreaded Programming in JavaMultithreaded Programming in Java
Java is the first widely used programming Java is the first widely used programming language to provide support for concurrent language to provide support for concurrent programming programming at the language levelat the language level
Java supports concurrency through the Java supports concurrency through the use of use of threadsthreads, and provides mechanisms , and provides mechanisms for synchronization between threadsfor synchronization between threads
Semantics of Multithreaded Java 4
Java Threads: ExampleJava Threads: Example
This example will illustrate the basic This example will illustrate the basic principles of multithreaded programming in principles of multithreaded programming in JavaJava
sumint aint bint c
sumEditorSum sum
sumPrinterSum sum
Semantics of Multithreaded Java 5
Java Threads: ExampleJava Threads: Example(Continued)(Continued)
public class Sum {public class Sum { int a, b, c;int a, b, c;
public Sum() {public Sum() { }}
public String toString() {public String toString() { return this.a + " + " + this.b + " = " + this.c;return this.a + " + " + this.b + " = " + this.c; }}}}
Semantics of Multithreaded Java 6
Java Threads: ExampleJava Threads: Example(Continued)(Continued)
public class SumEditor extends Thread {public class SumEditor extends Thread { Sum sum;Sum sum;
public SumEditor(Sum _sum) {public SumEditor(Sum _sum) { this.sum = _sum;this.sum = _sum; }}
public void run() {public void run() { for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { this.sum.a = i;this.sum.a = i; this.sum.b = i;this.sum.b = i; this.yield();this.yield(); this.sum.c = this.sum.a + this.sum.b;this.sum.c = this.sum.a + this.sum.b; }} }}}}
Semantics of Multithreaded Java 7
Java Threads: ExampleJava Threads: Example(Continued)(Continued)
public class SumPrinter extends Thread {public class SumPrinter extends Thread { Sum sum;Sum sum;
public SumPrinter(Sum _sum) {public SumPrinter(Sum _sum) { this.sum = _sum;this.sum = _sum; }}
public void run() {public void run() { for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { System.out.println(sum);System.out.println(sum); this.yield();this.yield(); }} }}}}
Semantics of Multithreaded Java 8
Java Threads: ExampleJava Threads: Example(Continued)(Continued)
public class ThreadingExperiment {public class ThreadingExperiment {
public ThreadingExperiment() {public ThreadingExperiment() { }}
public static void main(String[] args) {public static void main(String[] args) { Sum sum = new Sum();Sum sum = new Sum(); SumEditor sumEditor = new SumEditor(sum);SumEditor sumEditor = new SumEditor(sum); SumPrinter sumPrinter = new SumPrinter(sum);SumPrinter sumPrinter = new SumPrinter(sum);
System.out.println("main: starting threads");System.out.println("main: starting threads"); sumEditor.start();sumEditor.start(); System.out.println("main: started sumEditor thread");System.out.println("main: started sumEditor thread"); sumPrinter.start();sumPrinter.start(); System.out.println("main: started sumPrinter thread");System.out.println("main: started sumPrinter thread"); System.out.println("main: exiting");System.out.println("main: exiting"); }}}}
Semantics of Multithreaded Java 9
Java Threads: ExampleJava Threads: Example(Continued)(Continued)
Output from this exampleOutput from this example
main: starting threadsmain: started sumEditor threadmain: started sumPrinter threadmain: exiting1 + 1 = 02 + 2 = 23 + 3 = 44 + 4 = 65 + 5 = 86 + 6 = 107 + 7 = 128 + 8 = 149 + 9 = 16
Semantics of Multithreaded Java 10
Java Threads: ExampleJava Threads: Example(Continued)(Continued)
What’s going wrong?What’s going wrong?sumEditor sum sumPrinter
for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { this.sum.a = i;this.sum.a = i; this.sum.b = i;this.sum.b = i; this.yield();this.yield(); this.sum.c = this.sum.a this.sum.c = this.sum.a + this.sum.b;+ this.sum.b;}}
0
0
0
aa
bb
cc
for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { System.out.println(sum);System.out.println(sum); this.yield();this.yield();}}
1 + 1 = 0
1
1
2
Semantics of Multithreaded Java 11
Java Threads: SynchronizationJava Threads: Synchronization
Java provides two methods to synchronize Java provides two methods to synchronize threadsthreads Synchronized methodsSynchronized methods Synchronized statementsSynchronized statements
Both of these methods use Both of these methods use object locksobject locks to to enforce mutual exclusionenforce mutual exclusion
Only one thread can have a lock on an object at Only one thread can have a lock on an object at a timea time
If a thread attempts to obtain a lock on an object If a thread attempts to obtain a lock on an object that is already blocked, the thread will blockthat is already blocked, the thread will block
Semantics of Multithreaded Java 12
Java Threads: SynchronizationJava Threads: Synchronization(Continued)(Continued)
Synchronized MethodsSynchronized Methods Object to obtain lock on is implicitObject to obtain lock on is implicit
• Instance of class the synchronized method appears in for Instance of class the synchronized method appears in for non-static methodsnon-static methods
• Class method the synchronized method appears in for static Class method the synchronized method appears in for static methodsmethods
public synchronized Object getValue()public synchronized Object getValue()
Synchronized StatementsSynchronized Statements Object to obtain lock on is explicitObject to obtain lock on is explicit
synchronized (synchronized (object) object) {{
……
}}
Semantics of Multithreaded Java 13
Java Threads: SynchronizationJava Threads: Synchronization(Continued)(Continued)
Thread 1
Thread 2
Thread 3
Thread 4
object
Lock
Blockedobject
Blocked
Blocked
Lock
Semantics of Multithreaded Java 14
Java Threads: Synchronized ExampleJava Threads: Synchronized Example
public class SumEditor extends Thread {public class SumEditor extends Thread { Sum sum;Sum sum;
public SumEditor(Sum _sum) {public SumEditor(Sum _sum) { this.sum = _sum;this.sum = _sum; }}
public void run() {public void run() { for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { synchronized (sum) {synchronized (sum) { this.sum.a = i;this.sum.a = i; this.sum.b = i;this.sum.b = i; this.yield();this.yield(); this.sum.c = this.sum.a + this.sum.b;this.sum.c = this.sum.a + this.sum.b; }} }} }}}}
Semantics of Multithreaded Java 15
Java Threads: Synchronized ExampleJava Threads: Synchronized Example(Continued)(Continued)
public class SumPrinter extends Thread {public class SumPrinter extends Thread { Sum sum;Sum sum;
public SumPrinter(Sum _sum) {public SumPrinter(Sum _sum) { this.sum = _sum;this.sum = _sum; }}
public void run() {public void run() { for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { synchronized (sum) {synchronized (sum) { System.out.println(sum);System.out.println(sum); this.yield();this.yield(); }} }} }}}}
Semantics of Multithreaded Java 16
Java Threads: Synchronized ExampleJava Threads: Synchronized Example(Continued)(Continued)
Impact of synchronizationImpact of synchronizationsumEditor sum sumPrinter
for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { synchronized (sum) {synchronized (sum) { this.sum.a = i;this.sum.a = i; this.sum.b = i; this.sum.b = i; this.yield();this.yield(); this.sum.c = this.sum.a this.sum.c = this.sum.a + this.sum.b;+ this.sum.b; }}}}
0
0
0
aa
bb
cc
1 + 1 = 2
1
1
2
for (int i = 1; i < 10; i++) {for (int i = 1; i < 10; i++) { synchronized (sum) {synchronized (sum) { System.out.println(sum);System.out.println(sum); this.yield();this.yield(); }}}}
Semantics of Multithreaded Java 17
Memory ModelsMemory Models
When we discuss memory models, we When we discuss memory models, we really mean memory consistency modelsreally mean memory consistency models
A A memory consistency modelmemory consistency model should should provide a formal specification of how the provide a formal specification of how the memory system behavesmemory system behaves
This memory model essentially constrains This memory model essentially constrains the possible values that a read of a the possible values that a read of a variable can returnvariable can return
Semantics of Multithreaded Java 18
Memory ModelsMemory Models(Continued)(Continued)
Memory models allow a programmer to Memory models allow a programmer to reason about the potential outcomes of reason about the potential outcomes of both synchronized and unsynchronized both synchronized and unsynchronized programsprograms
Memory models take on special Memory models take on special significance with Java, where data races significance with Java, where data races could be used to compromise securitycould be used to compromise security
Semantics of Multithreaded Java 19
Memory Models: Memory Models: Sequential ConsistencySequential Consistency
Sequential consistency provides an Sequential consistency provides an intuitive model of memory consistencyintuitive model of memory consistency
Lamport defines a system to be Lamport defines a system to be sequentially consistent if:sequentially consistent if:
“the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the
operations of each individual processor appear in this sequence in the order specified by the program”
Semantics of Multithreaded Java 20
Memory Models: Memory Models: Sequential ConsistencySequential Consistency
(Continued)(Continued)
…
P1 P2 P3 P4 PN
Main MemoryMain Memory
Semantics of Multithreaded Java 21
Memory Models: Memory Models: Sequential ConsistencySequential Consistency
(Continued)(Continued)
…
P1 P2 P3 P4 PN
Main MemoryMain Memory
Semantics of Multithreaded Java 22
Strong / Relaxed Memory ModelsStrong / Relaxed Memory Models
Strong memory modelsStrong memory models, such as sequential , such as sequential consistency, severely restrict the set of potential consistency, severely restrict the set of potential optimizations that can be appliedoptimizations that can be applied For example, compiler optimizations such as code For example, compiler optimizations such as code
motion, register allocation, and common sub-motion, register allocation, and common sub-expression elimination are disallowed under expression elimination are disallowed under sequential consistency [Maessen 2000]sequential consistency [Maessen 2000]
Relaxed (or weak) memory modelsRelaxed (or weak) memory models relax relax memory ordering constraints to allow for certain memory ordering constraints to allow for certain optimizationsoptimizations
Semantics of Multithreaded Java 23
Memory Models: CoherenceMemory Models: Coherence
CoherenceCoherence is an example of a relaxed is an example of a relaxed memory modelmemory model
Coherence is similar to sequential Coherence is similar to sequential consistency, with the following relaxation:consistency, with the following relaxation: For a given processor/thread, the program For a given processor/thread, the program
order is maintained on a per-location basis order is maintained on a per-location basis
Semantics of Multithreaded Java 24
Memory Models: CoherenceMemory Models: Coherence
…
P1 P2
Main MemoryMain Memory
abcd
P2 PN
R(a)
R(b)
W(a)
W(b)
R(a)
R(b)
R(c)
W(a)
R(b)
W(d)
R(a)
W(d)
R(a)
W(c)
W(b)
Semantics of Multithreaded Java 25
Java Memory ModelJava Memory Model
The Java Memory Model (JMM) is defined in The Java Memory Model (JMM) is defined in Chapter 17 of the Chapter 17 of the Java Language SpecificationJava Language Specification
The JMM is hard to understandThe JMM is hard to understand Ambiguous in placesAmbiguous in places Complicated enough that even the authors of the Complicated enough that even the authors of the
Java Language Specification Java Language Specification didn’t completely didn’t completely understand itunderstand it
All current JVM implementations violate the All current JVM implementations violate the specification to some degreespecification to some degree
Semantics of Multithreaded Java 26
Java Memory Model: TerminologyJava Memory Model: Terminology
A A variablevariable refers to refers to Static variable of a loaded classStatic variable of a loaded class Field of an allocated objectField of an allocated object Element of an allocated arrayElement of an allocated array
All variables are stored in a All variables are stored in a main memorymain memory that is shared by all threadsthat is shared by all threads
Every thread has a Every thread has a working memory working memory where it keeps where it keeps working copiesworking copies of variables of variables
Semantics of Multithreaded Java 27
Java Memory ModelJava Memory Model
Main Memory
Thread 1
…Working Memory
Execution Engine
Buffer
Thread 2
Working Memory
Execution Engine
Buffer
Thread N
Working Memory
Execution Engine
Buffer
Semantics of Multithreaded Java 28
Java Memory ModelJava Memory Model(Continued)(Continued)
Main Memory
Thread 1
…Working Memory
Execution Engine
Buffer
Thread 2
Working Memory
Execution Engine
Buffer
Thread N
Working Memory
Execution Engine
Buffer
useuse
readread
assignassign
loadload
writewrite
storestore
Semantics of Multithreaded Java 29
Java Memory ModelJava Memory Model(Continued)(Continued)
Main Memory
Thread 1
…Working Memory
Execution Engine
Buffer
Thread 2
Working Memory
Execution Engine
Buffer
Thread N
Working Memory
Execution Engine
Buffer
lock/unlocklock/unlock
Semantics of Multithreaded Java 30
Java Memory ModelJava Memory Model(Continued)(Continued)
3
1
Main Memory
Thread 1
…Working Memory
Execution Engine
Buffer
Thread 2
Working Memory
Execution Engine
Buffer
Thread N
Working Memory
Execution Engine
Buffer
locklock
3
2 36
unlockunlock
1
3
2
3131 32
Semantics of Multithreaded Java 31
Java Memory Model: ExampleJava Memory Model: Example
When When Thread 1Thread 1 and and Thread 2Thread 2 have finished have finished executing, can we have: a = 1, b = 1?executing, can we have: a = 1, b = 1?
Answer: Yes!Answer: Yes!
Thread 2Thread 1
x = y = 0
a = x
y = 1
b = y
x = 1
Threads Begin
Jan-Willem Maessen, Arvind, Xiaowei Shen. Improving the Java Memory Model using CRF. In Proceedings of the 15th Annual Conference on Object-Oriented Programming Systems, Languages and Applications, Portland, OR, Oct. 2000.
Semantics of Multithreaded Java 32
Java Memory Model: Java Memory Model: Prescient StoresPrescient Stores
The JMM allows The JMM allows prescient storesprescient stores: storing the : storing the value that will be assigned to a variable by a value that will be assigned to a variable by a future assign operation before the assign occursfuture assign operation before the assign occurs
The prescient store of a variable The prescient store of a variable VV is allowed in is allowed in thread thread TT if the following conditions are satisfied: if the following conditions are satisfied: If the If the storestore on on VV occurs, the occurs, the assignassign is bound to occur is bound to occur No No locklock operation occurs between the operation occurs between the storestore and and
assignassign No No loadload of of VV occurs between the occurs between the storestore and and assignassign No other No other storestore of V occurs between the of V occurs between the storestore and and
assignassign
Semantics of Multithreaded Java 33
Java Memory Model: ExampleJava Memory Model: Example(Continued)(Continued)
Thread 2
x = y = 0
a = x
y = 1
b = y
x = 1
Threads Begin
Thread 1
load x
use x
assign y
store y
write y
read y
load y
use y
assign x
store x
write x
Main Memory
…
Working Memory
Execution Engine
Buffer
use
read
assign
load
write
store
Thread 1
Thread 2
read x
Semantics of Multithreaded Java 34
Java Memory Model: ExampleJava Memory Model: Example(Continued)(Continued)
load x
use x
assign y
store y
write y
read y
load y
use y
assign x
store x
write x
Thread 1
Thread 2
read x
write y
read x
load x
use x
assign y
read y
load y
use y
assign x
store x
write x
Thread 1
Thread 2
store y
Semantics of Multithreaded Java 35
Java Memory Model: VolatileJava Memory Model: Volatile
Variables declared Variables declared volatilevolatile are treated specially: are treated specially: Read from main memory on every Read from main memory on every useuse Written to main memory on every Written to main memory on every assignassign Accesses to Accesses to volatilesvolatiles are sequentially consistent (i.e. are sequentially consistent (i.e.
prescient stores not allowed)prescient stores not allowed) Access to Access to longlongs/s/doubledoubles are atomics are atomic
The memory semantics of accessing a volatile The memory semantics of accessing a volatile are similar to accessing an object exclusively are similar to accessing an object exclusively through synchronized get() and set() methods through synchronized get() and set() methods
Semantics of Multithreaded Java 36
Java Memory Model: FinalJava Memory Model: Final
Fields declared as Fields declared as finalfinal can only be can only be assigned to once in the constructor for the assigned to once in the constructor for the class in which they are definedclass in which they are defined The Java Memory Model does not discuss The Java Memory Model does not discuss
finalfinal fields at all! fields at all! Several optimizations for Several optimizations for finalfinal fields are fields are
obvious, but are not permitted under the obvious, but are not permitted under the current JMMcurrent JMM
Semantics of Multithreaded Java 37
Java Memory Model:Java Memory Model:SummarySummary
The JMM is difficult to understand – The JMM is difficult to understand – research papers that discuss the JMM research papers that discuss the JMM interpret it differentlyinterpret it differently
The JMM is at least as strong as The JMM is at least as strong as CoherenceCoherence
William Pugh has shown that the JMM is William Pugh has shown that the JMM is actually stronger than Coherenceactually stronger than Coherence
Semantics of Multithreaded Java 38
Problems with the Problems with the Java Memory ModelJava Memory Model
Three main problems exist with the current Three main problems exist with the current Java Memory Model:Java Memory Model: It prohibits many important compiler It prohibits many important compiler
optimizationsoptimizations It is incomplete: the semantics for It is incomplete: the semantics for finalfinal fields fields
are not definedare not defined It is hard to interpretIt is hard to interpret
Semantics of Multithreaded Java 39
Problems with the JMM:Problems with the JMM:Compiler OptimizationsCompiler Optimizations
The JMM requires Coherence, which prohibits The JMM requires Coherence, which prohibits many important compiler optimizationsmany important compiler optimizations
A compiler would not be permitted to perform A compiler would not be permitted to perform fetch eliminationfetch elimination
w = q.f
x = p.f
v = p.f
p.f = 2
Thread 1 Thread 2
If p == q at runtime(p and q are aliased)
w = p.f
x = p.f
v = p.f
p.f = 2
Thread 1 Thread 2
x = v x = v
Semantics of Multithreaded Java 40
Problems with the JMM:Problems with the JMM:Semantics of FinalSemantics of Final
The current JMM does not provide any The current JMM does not provide any discussion of discussion of finalfinal fields fields
Final fields are another potential source of Final fields are another potential source of optimizations that cannot be performed optimizations that cannot be performed under the current JMMunder the current JMM
Current semantics may result in immutable Current semantics may result in immutable objects appearing mutableobjects appearing mutable
Semantics of Multithreaded Java 41
Problems with the JMM:Problems with the JMM:ComplexityComplexity
The three stages presented in the JMM The three stages presented in the JMM make it difficult to reason about the order make it difficult to reason about the order of memory operationsof memory operations
Main Memory
Working Memory
Execution Engine
Buffer
use
read
assign
load
write
store
Thread
Semantics of Multithreaded Java 42
The current JMM is complex and The current JMM is complex and restrictive enough that all current JVM restrictive enough that all current JVM implementations violate it to some degreeimplementations violate it to some degree
Pugh suggests that the JMM, in its current Pugh suggests that the JMM, in its current form, will never be clear. New proposals form, will never be clear. New proposals for semantics, such as those in for semantics, such as those in Semantics Semantics of Multithreaded Javaof Multithreaded Java, should offer a , should offer a completely new descriptioncompletely new description
Problems with the JMM:Problems with the JMM:ComplexityComplexity
(Continued)(Continued)
Semantics of Multithreaded Java 43
ReferencesReferences Sarita V. Adve and Kourosh Gharacholoo. Shared Memory Consistency Sarita V. Adve and Kourosh Gharacholoo. Shared Memory Consistency
Models: A Tutorial. Models: A Tutorial. Rice University ECE Technical Report 9512.Rice University ECE Technical Report 9512. James Gosling, Bill Joy, Guy Steele, Gilad BrachaJames Gosling, Bill Joy, Guy Steele, Gilad Bracha. The Java Language . The Java Language
Specification, Second Edition.Specification, Second Edition. David Holmes. The Java Memory Model: Defining Concurrency David Holmes. The Java Memory Model: Defining Concurrency
Correctness on Multiprocessors. Correctness on Multiprocessors. http://www.csse.monash.edu.au/courseware/cse3420/Lectures/Module11/http://www.csse.monash.edu.au/courseware/cse3420/Lectures/Module11/dholmes.ppt.dholmes.ppt.
Jan-Willem Maessen, Arvind, Xiaowei Shen. Improving the Java Memory Jan-Willem Maessen, Arvind, Xiaowei Shen. Improving the Java Memory Model using CRF. Model using CRF. In Proceedings of the 15th Annual Conference on Object-In Proceedings of the 15th Annual Conference on Object-Oriented Programming Systems, Languages and Applications, Portland, Oriented Programming Systems, Languages and Applications, Portland, OR, Oct. 2000.OR, Oct. 2000.David Mosberger. Memory Consistency Models. David Mosberger. Memory Consistency Models. University of Arizona University of Arizona Technical Report 93/11.Technical Report 93/11.
William Pugh. Fixing the Java Memory Model. William Pugh. Fixing the Java Memory Model. Java Grande Conference, Java Grande Conference, June 12-14, 1999.June 12-14, 1999.
William Pugh. The Java Memory Model is Fatally Flawed. William Pugh. The Java Memory Model is Fatally Flawed. Concurrency: Concurrency: Practice and Experience.Practice and Experience.