Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0...

28
CIT Concurrency Concurrency in JDK 5.0 Thread-safe collections, Task Management, Synchronizers, Low- level Facilities

Transcript of Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0...

Page 1: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency Concurrency in JDK 5.0

Thread-safe collections, Task Management, Synchronizers, Low-

level Facilities

Page 2: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Java Implicit Concurrency (1)• AWT and Swing

– Background event thread– Event Listener classes must be thread-safe

• TimeTask – scheduling and periodic execution of tasks– TimerTask events execute in the Timer thread– TimerTasks must be thread safe

• Servlets and JavaServer Pages– Servlet containers create multiple threads and may call a

given servlet concurrently from multiple threads for multiple requests

– Servlets classes must be thread safe• RMI

– Remote classes must be thread safe

Page 3: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Java Implicit Concurrency (2)• Thread safe class

– Must behave correctly in a single-threaded environment• No sequence of operations (public interface) puts objects in an

invalid state, • Or observe the object to be in an invalid state• Or violate any of the class’s invariants, pre- and post-

conditions

– Must continue to behave correctly when accessed from multiple threads

• Regardless of the scheduling or interleaving of the execution ofthose threads by the runtime environment

• Without any additional synchronisation on the part of the calling code

Page 4: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Java Implicit Concurrency (3)• JDK 5.0

– java.util.concurrent– JVM-level changes (exploitation of hardware

level concurrency support – compare-and-swap instruction)

– Low-level utility classes – locks and atomic variables

– High-level utility classes – OS constructs (e.g. semaphores, mutexes, barriers), thread pools and thread-safe collection classes

Page 5: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Thread-safe collections (1)• Collections

– Some are already thread safe: Hashtable and Vector– The rest can be made thread safe: syncrhonised wrapper

factories Collections.synchronisedList/Map/Set– Need to hold a lock while iterating!

• Fail-fast iterators• ConcurrentModificationException – conditional thread-safety

• java.util.concurrent– ConcurrentHashMap, CopyOnWriteArrayList,

CoppyOnWriteArraySet, Queue, BlockingQueue• Weakly consistent iterators

– A removed item not already returned will not be returned– An added item after the start of the iteration may or may not be

returned– No element will be returned twice in a single iteration

Page 6: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Thread-safe collections (2)• CopyOnWriteArrayList/Set

– A new copy is created whenever an element is added or removed

– Avoids locking during iteration– Useful for list of listeners

• ConcurrentHashMap– Cannot be locked for exclusive use, but provides atomic

methods for common compound operations, e.g. put-if-absent

– Returns weakly consistent iterators• Queue interface – FIFO and priority classes• BlockingQueue – bounded or unbounded

– Producer/Consumer

Page 7: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Bounded Buffer (1)• A bounded buffer consists of a fixed number of

slots– Items are put into the buffer by a producer process and

removed by a consumer process – It can be used to smooth out transfer rates between the

producer and consumer

Page 8: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Bounded Buffer (2)public interface Buffer {…}

class BufferImpl implements Buffer {…

public synchronized void put(Object o) throws InterruptedException {

while (count==size) wait();buf[in] = o; ++count; in=(in+1)%size;notify();

}public synchronized Object get()

throws InterruptedException {while (count==0) wait();Object o =buf[out]; buf[out]=null; --count; out=(out+1)%size;notify();return (o);}

}

We separate the interface to permit an alternative implementation later.

Page 9: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Bounded Buffer (3)class Producer implements Runnable {

Buffer buf;String alphabet= "abcdefghijklmnopqrstuvwxyz";

Producer(Buffer b) {buf = b;}

public void run() {try {

int ai = 0;while(true) {

ThreadPanel.rotate(12);buf.put(new Character(alphabet.charAt(ai)));ai=(ai+1) % alphabet.length();ThreadPanel.rotate(348);

}} catch (InterruptedException e){}

}}

Similarly Consumer which calls buf.get()

Page 10: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Bounded Buffer (4)• The same in java 5.0

– The buffer

– The consumer

– The producer

LinkedBlockingQueue<Character> buf = new LinkedBlockingQueue<Character>(n);

buf.put(new Character(alphabet.charAt(ai)));

Character c = buf.take();

Page 11: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Task Management (1)• Executor interface

– Objects that run Runnables– Separate task submission from task execution policy– Various threading options: background thread, thread

pool, in the calling thread (pass-through), new thread (thread-per-request), in another JVM

– Instantiation through factory methods• Executors.newCachedThreadPool()• Executors.newFixedThreadPool(int n)• Executors.newSingleThreadExecutor()

• ExecutorService interface– Extension of executor with lifecycle management of

execution service

Page 12: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Task Management (2)class ReliableWebServer {

Executor pool = Executors.newFixedThreadPool(7);public static void main(String[] args) {

ServerSocket socket = new ServerSocket(80);while (true) {

final Socket connection = socket.accept();Runnable r = new Runnable() {

public void run() {handleRequest(connection);

}};pool.execute(r);

}}

}

Page 13: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Task Management (3)• Executor customisation through custom

ThreadFactory• In case of execution inability –

RejectedExecutionHandler– Throw exception– Discard task– Execute in caller’s thread– Discard old task in queue

• Custom executors with overidden beforeExecuteand afterExecute– Instrumentation, logging, timing, reinitialisation of

thread-local variables, execution customisations

Page 14: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Task Management (4)• Callable: result bearing Runnable• Future interface

– FutureTask – implements interface, can be submitted to an Executor

• ExecutorService.submit() – returns a Future interface

– Future.get() – retrieves results or throws ExecutionException – it is blocking

• CompletionService interface– Decouple results processing from task

execution, e.g. producer/consumer– ExecutorCompletionInterface

Page 15: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Task Management (5)public class Cache<K, V> {

ConcurrentMap<K, FutureTask<V>> map = new ConcurrentHashMap();

Executor executor = Executors.newFixedThreadPool(8);public V get(final K key) {

FutureTask<V> f = map.get(key);if (f == null) {

Callable<V> c = new Callable<V>() {public V call() {

// return value associated with key}

};f = new FutureTask<V>(c);FutureTask old = map.putIfAbsent(key, f);if (old == null) executor.execute(f);else f = old;

}return f.get();

}}

Page 16: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Semaphores (1)• Semaphore s is an

integer variable that can take only non-negative values– Semaphores are widely

used for dealing with inter-process synchronization in operating systems

• The only operations permitted on s are up(s) and down(s)– Blocked processes are

held in a FIFO queue.

down(s): if s >0 thendecrement s

elseblock execution of the calling process

up(s): if processes blocked on s thenawaken one of them

elseincrement s

Page 17: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Semaphores (2)

public class Semaphore {

private int value;

public Semaphore (int initial) { value = initial;}

synchronized public void up() {++value;notify();

}

synchronized public void down()throws InterruptedException {

while (value==0) wait();--value;

}}

Page 18: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Bounded Buffer (2)public interface Buffer {…}

class BufferImpl implements Buffer {…

public synchronized void put(Object o) throws InterruptedException {

while (count==size) wait();buf[in] = o; ++count; in=(in+1)%size;notify();

}public synchronized Object get()

throws InterruptedException {while (count==0) wait();Object o =buf[out]; buf[out]=null; --count; out=(out+1)%size;notify();return (o);}

}

We separate the interface to permit an alternative implementation later.

Page 19: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Nested Monitors (1)• Suppose that, in place of using the count variable

and condition synchronization directly, we instead use two semaphores full and empty to reflect the state of the buffer. class SemaBuffer implements Buffer {

Semaphore full; //counts number of itemsSemaphore empty; //counts number of spaces

SemaBuffer(int size) {this.size = size; buf = new Object[size];full = new Semaphore(0);empty= new Semaphore(size);

}…}

Page 20: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Nested Monitors (2)

• Empty is decremented during a put operation, which is blocked if empty is zero

• Full is decremented by a get operation, which is blocked if full is zero.

synchronized public void put(Object o) throws InterruptedException {

empty.down();buf[in] = o;++count; in=(in+1)%size;full.up();

}synchronized public Object get()

throws InterruptedException{full.down();Object o =buf[out]; buf[out]=null;--count; out=(out+1)%size;empty.up();return (o);

}

Does this behave as desired?

Page 21: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Nested Monitors (3)• The only way to avoid nested monitor deadlock in

Java is by careful design– In this example, the deadlock can be removed by

ensuring that the monitor lock for the buffer is not acquired until after semaphores are decremented.

public void put(Object o) throws InterruptedException {

empty.down();synchronized(this){buf[in] = o; ++count; in=(in+1)%size;

}full.up();

}

Page 22: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Syncrhonizer Classes• Coordination and control of execution flow of threads• Semaphore

– Thread acquire any number of permits– Mutex – mutual exclusion semaphore or binary semaphore

• Similar to locks but allow release from different thread – useful in deadlock recovery

• CyclicBarrier– Reusable barrier for a group of threads– Maybe used with a timeout

• CountdownLatch– Similar to barrier but not reusable– Separates barrier arrival from waiting– Can be used as a starting gate

• Exchanger– Rendezvous– Similar to a barrier of two but with data exchange

Page 23: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Readers/Writers (1)• A shared database is accessed by two kinds of

processes. Readers execute transactions that examine the database while Writers both examine and update the database. A Writer must have exclusive access to the database; any number of Readers may concurrently access it.

Light blue indicates database access.

Page 24: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Readers/Writers (2)• We concentrate on the monitor implementation• We define an interface that identifies the monitor

methods that must be implemented, and develop a number of alternative implementations of this interface. – Firstly, the safe READWRITELOCK.

interface ReadWrite {public void acquireRead()

throws InterruptedException;public void releaseRead();public void acquireWrite()

throws InterruptedException;public void releaseWrite();

}

Page 25: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Readers/Writers (3)class ReadWriteSafe implements ReadWrite {

private int readers =0;private boolean writing = false;

public synchronized void acquireRead()throws InterruptedException {

while (writing) wait();++readers;

}

public synchronized void releaseRead() {--readers;if(readers==0) notify();

}

Unblock a single writer when no more readers.

Page 26: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Readers/Writers (4)public synchronized void acquireWrite()

throws InterruptedException {while (readers>0 || writing) wait();writing = true;

}

public synchronized void releaseWrite() {writing = false;notifyAll();

}}

Unblock all readers

This monitor implementation suffers from the WRITE progress problem: possible writer starvation if the number of readersnever drops to zero.

Strategy: Block readers if there is a writer waiting.

Page 27: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Readers/Writers (5)class ReadWritePriority implements ReadWrite{

private int readers =0;private boolean writing = false;private int waitingW = 0; // no of waiting Writers.public synchronized void acquireRead()

throws InterruptedException { while (writing || waitingW>0) wait();

++readers; }public synchronized void releaseRead() { --readers; if (readers==0) notify(); }synchronized public void acquireWrite() { ++waitingW;

while (readers>0 || writing) try{ wait();} catch(InterruptedException e){}

--waitingW; writing = true; }synchronized public void releaseWrite() { writing = false; notifyAll(); }

}

Both READand WRITEprogress properties can be satisfied by introducing a turnvariable as in the Single Lane Bridge.

Page 28: Concurrency in JDK 5.0 CIT Concurrency · CIT Concurrency Java Implicit Concurrency (3) •J DK 5.0 – java.util.concurrent – JVM-level changes (exploitation of hardware level

CIT

Con

curr

ency

Low-Level facilities• Locks

– Lock interface– Like the syncrhonized lock but with variations

• Timed waits, interruptible waits, lock polling, multiple condition wait sets per lock, non-blocking structured locking

– Reentrant lock implements interface• More scalable than synchronised• But, requires explicit unlocking

– Condition interface • Generalisation of wait()/notify() • Multiple conditions on the same lock

– ReadWriteLock– Can be fair, but fairness doesn’t scale

• Atomic variables– AtomicInteger/Long/Boolean/etc.