Post on 04-Jul-2020
Concurrent programming in Java
INF4140
12.10.11
Lecture 7
Agenda
basic Java threads programming:
Java threads: de�nitions, properties
Interference
Locking and synchronization
Waiting and signalling
Running example: readers and writers
Experiences and high level structures:
Deadlock, problems with lexical locking
High level structures for concurrent programming (Java 5.0)
Example: bounded bu�er
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 2 / 1
Operating systems, processes, and threads
OS es
allow several processes to run on one machine via preemptivescheduling.Multi-processor machines or �multi-core�-processors: processes can alsorun truly concurrently/in parallel
Thread :
a process that is inexpensive for the OS to create, typically becauseresources are shared with the process that created the thread.Resource sharing enables e�ective interaction between threads, but canalso lead to interference between threads.
Java
and the Java Virtual Machine (JVM): independent of the OSJava threads are built into the language.=⇒ threads must follow certain rules.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 3 / 1
Concrete de�nition of Java threads
Listing 1: java.lang.Thread
p u b l i c c l a s s Threadex t end s Objectimplements Runnable
{// c o n s t r u c t o r sThread ( ) { . . . }Thread ( Runnable t a r g e t ) { . . . }
// methods// must be re−implemented by s u b c l a s s e sp u b l i c vo i d run ( ) {}p u b l i c vo i d s t a r t ( ). . . // much omi t ted
}
// a r e l a t e d i n t e r f a c ep u b l i c i n t e r f a c e Runnable {
p u b l i c vo i d run ( ) ;}
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 4 / 1
Basic properties of Java threads
Each thread is controlled by a unique Thread object� these two can be treated as one.Lifecycle for one thread:
An object of class Thread is created
Life (execution) begins when the run() is called
The thread dies when run() terminates, either by returningor an exception
Threads typically communicate via shared state :
Read/write �elds in objects the threads can reference
Local variables and method parameters: not shared between threads
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 5 / 1
Threads in Java: A �rst example
de�ne::
c l a s s S imple e x t end s Thread {p u b l i c vo i d run ( ) {
System . out . p r i n t l n (" He l l o th r eaded wor ld ! " ) ;} }
use:
Simple s = new Simple ( ) ;s . s t a r t ( ) ;
start(): prepares the object for execution.
when processor becomes available: �it� calls s.run().
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 6 / 1
Example: interference and Java threads
avoid interference during concurrent execution of Java threads.
c l a s s S to r e {p r i v a t e i n t data = 0 ;p u b l i c vo i d update ( ) { data++; }
}. . .// i n a method :S to r e s = new Sto r e ( ) ; // the t h r e ad s below have a c c e s s to st1 = new FooThread ( s ) ; t1 . s t a r t ( ) ;t2 = new FooThread ( s ) ; t2 . s t a r t ( ) ;
Threads t1 and t2 could execute s.update() concurrently!Interference between t1 and t2 =⇒ may lose updates to data.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 7 / 1
Locks and synchronization
To avoid interference: Threads synchronize access to shared dataMechanism:
1 One unique lock for each object1 o.
2 mutex: at most one thread T can lock o at any time.
3 T makes a
request to lock o in order to execute the block (statements) B as follows:
synchronized (o) { B }
T blocks (�stops�) until the lock succeeds.
4 As soon as (if) T 's request succeeds, o is locked and T executes B .
5 Several threads can compete in the locking of an object.Implementation-dependent order for granting of lock requests.
6 T may lock o again from B (� reentrance �).
7 When T �nishes B or throws an exception: lock on o is released.
1Actually: object, table, and class.INF4140 (12.10.11) Concurrent programming in Java Lecture 7 8 / 1
State model for Java threads: locking
new
��
gfed`abcrequestfor o
locked o
��
_^]\XYZ[createdstart()
// _^]\XYZ[readyscheduled
11 _^]\XYZ[running
synchronized (o)
bbEEEEEEEEEEEEEEEEEEpreemptedqq
The lock on o is released when the thread leaves the synchronized block(must happen in state `running').Some conditions and thread primitives omitted.2
2Taken from the book Java Precisely by Peter Sestoft (MIT Press, 2002 & 2005).Old version freely availably from http://www.dina.dk/~sestoft/javaprecisely/
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 9 / 1
Example part II: no interference
Solution to earlier problem: lock the Store objects before executingproblematic method:
c l a s s Sto r e {p r i v a t e i n t data = 0 ;pub l i c vo id update ( ) {
synchron ized ( t h i s ) { data++; }} }\ dot s// i n s i d e a method :Sto r e s = new Sto r e ( ) ;
Now only one thread at a time can run s.update().Short form:
c l a s s S to r e {p r i v a t e i n t data = 0 ;p u b l i c s y n ch r on i z e d vo i d update ( ) {
data++;} }
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 10 / 1
Example: Sequential readers and writers
c l a s s RWbasic {p r o t e c t e d i n t data = 0 ; // the " database "p u b l i c vo i d read ( ) { System . out . p r i n t l n (" read : " + data ) ; }p u b l i c vo i d w r i t e ( ) {
data++;System . out . p r i n t l n (" wrote : " + data ) ;
} }
c l a s s Main {s t a t i c RWbasic RW = new RWbasic ( ) ;p u b l i c s t a t i c vo i d main ( S t r i n g [ ] a rg ) {
f o r ( i n t i = 0 ; i < 10 ; i++) {RW. read ( ) ;RW. w r i t e ( ) ;
} } }
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 11 / 1
Example: Parallel (unsynchronized)readers and writers
c l a s s Reader e x t end s Thread {RWbasic RW; // As b e f o r ep u b l i c Reader ( RWbasic RW) {
t h i s .RW = RW;}p u b l i c vo i d run ( ) {
f o r ( i n t i = 0 ; i < 10 ; i++)RW. read ( ) ;
}}
c l a s s Wr i t e r . . .// l i k e Reader , but RW. w r i t e ( ) i n s t e a d
c l a s s Main {s t a t i c RWbasic RW = new RWbasic ( ) ;p u b l i c s t a t i c vo i d main ( S t r i n g [ ] a rg ) {
new Reader (RW) . s t a r t ( ) ;new Wr i t e r (RW) . s t a r t ( ) ;
}}
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 12 / 1
Example: Exclusive readers and writers
Synchronized methods give mutual exclusion.
c l a s s RWexc lus ive ex t end s RWbasic {p u b l i c s y n ch r on i z e d vo i d read ( ) { supe r . r ead ( ) ; }p u b l i c s y n ch r on i z e d vo i d w r i t e ( ) { supe r . w r i t e ( ) ; }
}
ie reuses code from class RWbasic.
The classes Reader, Writer and Main now use RWexclusive instead ofRWbasic.
No interference, but. . .Problem: At most one reader at a time.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 13 / 1
Methods for waiting and signalling
p u b l i c c l a s s Object {// methodsp u b l i c f i n a l v o i d wa i t ( )
throws I n t e r r u p t e dE x c e p t i o n { . . . }p u b l i c f i n a l v o i d n o t i f y ( ) { . . . }p u b l i c f i n a l v o i d n o t i f y A l l ( ) { . . . }
. . . // much omi t ted}
A thread that calls methods on object o must have locked o beforehand,typically
s y n ch r on i z e d ( o ) {. . .o . wa i t ( ) ;
. . .}
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 14 / 1
Explanation of wait-related methods
The following is de�ned for an arbitrary Java object o:
o.wait(): release lock on o, enter o's wait queue and wait
o.notify(): wake up one thread in o's wait queue
o.notifyAll(): wake up all threads in o's wait queue
Objects that wait on o (o.wait()) sit in a queue.The ordering of the wait queue is implementation-dependent.The methods notify()/notifyAll() have �Signal and Continue�semantics.
Note: A thread which wakes from o.wait() must lock o again before itcontinues.An awakened thread has no advantage in the competition for the lock to o.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 15 / 1
State model for Java threads: locking and waiting
new
��
gfed`abcrequestfor o
locked o
��
gfed`abcwaitingfor o
interrupt()
mm
o.notify or
o.notifyAllqq
_^]\XYZ[createdstart()
// _^]\XYZ[readyscheduled
11 _^]\XYZ[running
synchronized (o)EEEEEEEE
bbEEEEEEEE
preemptedqq
o.wait()
RR
There are two independent places where a thread can block, per object o:
by locking o: synchronized (o) { B }
by waiting on o: o.wait()
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 16 / 1
Example: Real readers and writers
c l a s s Reade r sWr i t e r s e x t end s RWbasic {p r i v a t i n t nr = 0 ;p r i v a t e s y n ch r on i z e d vo i d s t a r tRead ( ) { nr++;}p r i v a t e s y n ch r on i z e d vo i d endRead ( ) {
nr−−;i f ( nr==0) n o t i f y ( ) ; // awaken wa i t i n g Wrs .
}p u b l i c vo i d read ( ) { // not s y n ch r on i z e d
s t a r tRead ( ) ; s upe r . r ead ( ) ; endRead ( ) ;}p u b l i c s y n ch r on i z e d vo i d w r i t e ( ) {
wh i l e ( nr >0)t r y { wa i t ( ) ; }
ca tch ( I n t e r r u p t e dE x c e p t i o n ex ){ r e t u r n ; }
supe r . w r i t e ( ) ;n o t i f y ( ) ; // awaken ano the r wa i t i n g W.
}}
The classes Reader, Writer and Main now use ReadersWriters insteadof RWbasic.Problem: The solution favours readers (�starvation�).
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 17 / 1
Deadlock
T1 : T2 :
s y n ch r on i z e d ( a ) { s y n ch r on i z e d ( b ) {. . . . . .s y n ch r on i z e d ( b ) { s y n ch r on i z e d ( a ) {
. . . . . .} }. . . . . .
} }
Deadlock if T1 locks a and then T2 locks b.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 18 / 1
Lexical (blockwise) locking
ie locking using synchronized:Advantages:
Automatic unlocking at the end of the synchronized block
Transparent, easy to see when a lock is held
Disadvantages:
When several objects are locked: locks must be released in reverseorder
Locks must be released in the same lexical scope that they werelocked in
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 19 / 1
High-level constructions for concurrent programming
Java (5.0) supports concurrent programming at a high level of abstractionin the packages java.util.concurrent*.Motivation for high-level support:
More �exible and/or abstract than synchronized
E�cient implementations, do not use synchronized directly
Correct implementations of synchronization primitives, e.g.semaphores (frequently a non-trivial task!)
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 20 / 1
Flexible locks with conditions
Listing 2: Interface java.util.concurrent.locks.Lock
p u b l i c i n t e r f a c e Lock {// methodsp u b l i c vo i d l o c k ( ) ;p u b l i c vo i d un lock ( ) ;p u b l i c boo l ean t r y l o c k ( ) ;p u b l i c Cond i t i on newCond i t ion ( ) ;
. . . // omi t ted}
Listing 3: Interface java.util.concurrent.locks.Condition
p u b l i c i n t e r f a c e Cond i t i on {p u b l i c vo i d awa i t ( ) throws I n t e r r u p t e dE x c e p t i o n ;p u b l i c vo i d s i g n a l ( ) ;p u b l i c vo i d s i g n a l A l l ( ) ;
. . . // omi t ted}
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 21 / 1
Standard implementation and semantics
O�ered as standard:
Listing 4: Class java.util.concurrent.locks.ReentrantReadWriteLock
p u b l i c c l a s s Reent rantReadWr i teLockex t end s Objectimplements ReadWriteLock , . . .{ . . . }
Semantics of �exible locks
The same number of calls must be made to lock() and unlock() foreach lock
Methods in Condition have � signal and continue � behaviour
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 22 / 1
Use of �exible locks
Lock l = . . . ;l . l o c k ( ) ;t r y {
. . . // a c c e s s e s the r e s o u r c e p r o t e c t e d by the l o c k} f i n a l l y {
l . un l ock ( ) ;}
Code executed when the lock is held should be protected by try-finallyor similar to ensure that the lock is released in case of interruption.A condition associated with a lock is created as follows:
Lock l = . . . ;Cond i t i on c = l . newCond i t ion ( ) ;
The lock must be held when the condition is used.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 23 / 1
Eg.: bounded bu�er using Condition
c l a s s BoundedBuf fer {f i n a l Lock l o c k = new Reent rantLock ( ) ;f i n a l Cond i t i on n o t F u l l = l o c k . newCond i t ion ( ) ;f i n a l Cond i t i on notEmpty = l o c k . newCond i t ion ( ) ;
f i n a l Object [ ] buf = new Object [ 1 0 0 ] ;i n t r ea r , f r on t , count ; // i n t d e f a u l t s to 0
p u b l i c vo i d d e p o s i t ( Object x ) throws I n t e r r u p t e dE x c . { . . . }
p u b l i c Object f e t c h ( ) throws I n t e r r u p t e dE x c e p t i o n { . . . }
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 24 / 1
Eg.: bounded bu�er using Condition
c l a s s BoundedBuf fer {. . . // i n i t i a l i z a t i o np u b l i c vo i d d e p o s i t ( Object x ) throws I n t e r r u p t e dE x c . {
l o c k . l o c k ( ) ;t r y {
wh i l e ( count == buf . l e n g t h ) n o t F u l l . awa i t ( ) ;buf [ r e a r ] = x ;r e a r = ( r e a r + 1) % buf . l e n g t h ;count++;
notEmpty . s i g n a l ( ) ;} f i n a l l y { l o c k . un lock ( ) ; }
}
. . . .
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 25 / 1
Eg.: bounded bu�er using Condition
c l a s s BoundedBuffer {. . . // i n i t i a l i z a t i o n
. . .
p u b l i c Object f e t c h ( ) throws I n t e r r u p t e dE x c e p t i o n {l o c k . l o c k ( ) ;t r y {
wh i l e ( count == 0) notEmpty . awa i t ( ) ;Object x = buf [ f r o n t ] ;f r o n t = ( f r o n t + 1) % buf . l e n g t h ;count−−;n o t F u l l . s i g n a l ( ) ;r e t u r n x ;
} f i n a l l y { l o c k . un l ock ( ) ; }} }
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 26 / 1
Eg.: bounded bu�er using Condition
c l a s s BoundedBuffer {f i n a l Lock l o c k = new Reent rantLock ( ) ;f i n a l Cond i t i o n n o t F u l l = l o c k . newCond i t ion ( ) ;f i n a l Cond i t i o n notEmpty = l o c k . newCond i t ion ( ) ;
f i n a l Object [ ] bu f = new Object [ 1 0 0 ] ;i n t r ea r , f r o n t , count ; // i n t d e f a u l t s to 0
p u b l i c v o i d d e p o s i t ( Object x ) throws I n t e r r u p t e dEx c . {l o c k . l o c k ( ) ;t r y {
wh i l e ( count == buf . l e n g t h ) n o t F u l l . awa i t ( ) ;bu f [ r e a r ] = x ;r e a r = ( r e a r + 1) % buf . l e n g t h ;count++;
notEmpty . s i g n a l ( ) ;} f i n a l l y { l o c k . un l ock ( ) ; }
}p u b l i c Object f e t c h ( ) throws I n t e r r u p t e dE x c e p t i o n {
l o c k . l o c k ( ) ;t r y {
wh i l e ( count == 0) notEmpty . awa i t ( ) ;Object x = buf [ f r o n t ] ;f r o n t = ( f r o n t + 1) % buf . l e n g t h ;count−−;n o t F u l l . s i g n a l ( ) ;r e t u r n x ;
} f i n a l l y { l o c k . un l ock ( ) ; }} }
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 27 / 1
Concurrent programming is di�cult. . .
Method stop() in class Thread:
Stops arbitrary threads
Stopping can break invariants in locked objects
Eventually declared deprecated.
For a long time, there were severe errors in Java's memory model:
�Double-checked locking� � a common idiom in concurrentprogramming � was invalid in Java
Errors and ambiguities in the de�nition of low-level behaviour of Javathreads
Corrected in 5.0 Java Language Speci�cation, 3rd edition.
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 28 / 1
JR language
The language JR is Java extended with language support for bothconcurrent and distributed programming.JR represents an alternative approach, inspired by Andrews' language SRwhich is used in the textbook.A JR implemention is freely available for various operating systems.
The JR Concurrent Programming Language,http://www.cs.ucdavis.edu/~olsson/research/jr/
INF4140 (12.10.11) Concurrent programming in Java Lecture 7 29 / 1