44
CIT Concurrency Java and Concurrency

Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

  • Upload
    others

  • View
    62

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency Java and Concurrency

Page 2: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

What do we need for concurrency?• Process creation

– How do you specify concurrent processes?• Communication

– How do processes exchange information?• Synchronization

– How do processes maintain consistency?

Page 3: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Java Threads (1)• A Thread class manages a single sequential

thread of control• Threads may be created and deleted

dynamicallyThread

run()

MyThread

run()

class MyThread extends Thread {public void run() {

//......}

}

Thread x = new MyThread();

Page 4: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Java Threads (2)• Since Java does not permit multiple

inheritance, we often implement the run() method in a class not derived from Thread but from the interface Runnable

Runnable

run()

MyRun

run()

public interface Runnable {public abstract void run();

}

class MyRun implements Runnable{public void run() {

//.....}

}

Threadtarget

Thread x = new Thread(new MyRun());

Page 5: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

java.lang.Threadpublic class java.lang.Thread extends java.lang.Objectimplements java.lang.Runnable {public Thread();public Thread(Runnable target);public Thread(Runnable target, String name);public Thread(String name);public void run();public synchronized void start();public static void sleepsleep(long millis)throws InterruptedException;public static void yieldyield();public final String getName();…}

Page 6: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Java Thread lifecycle (1)

Created Alive

Terminated

new Thread()

start()

stop(), orrun() returnsstop()

start() causes the thread to call its run() method.

The predicate isAlive() can be used to test if a thread has been started but not terminated. Once terminated, it cannot be restarted

Page 7: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Java Thread lifecycle (2) – Alive

Runnable Non-Runnablesuspend()

resume()

yield()

Running

dispatch

suspend()

start()

stop(), orrun() returns

sleep()

wait() also makes a Thread Non-Runnable, and notify() Runnable

NOTE: suspend(), resume() and stop() are now deprecated

Page 8: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Clock Applet Example (1)public class Clock extends java.applet.Appletimplements Runnable {

Thread clockThread = null;

public void start() {if (clockThread == null) {clockThread = new Thread(this, "Clock");clockThread.start()

}} ...

Page 9: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Clock Applet Example (2)...

public void run() {// stops when clockThread is set to nullwhile(Thread.currentThread()==clockThread) {repaint();try {clockThread.sleep(1000);

} catch (InterruptedException e){ }}

}...

Page 10: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Clock Applet Example (3)...

public void paint(Graphics g) {Date now = new Date();g.drawString(now.getHours()+ ":" + now.getMinutes()+ ":" + now.getSeconds(), 5, 10);

}

// When the applet stops, stop its threadpublic void stop() {clockThread = null;

}}

Page 11: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Count Down Timer Example (1)

Applet

init()start()stop()run()tick()beep()

Runnable

CountDown

NumberCanvas

setvalue()

Threadcounter

display

target

Page 12: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Count Down Timer Example (2)public class CountDown extends Applet

implements Runnable {Thread counter; int i;final static int N = 10;AudioClip beepSound, tickSound;NumberCanvas display;

public void init() {...}public void start() {...}public void stop() {...}public void run() {...}private void tick() {...}private void beep() {...}

}

Page 13: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Count Down Timer Example (3)public void start() {

counter = new Thread(this);i = N; counter.start();

}

public void stop() {counter = null;

}

public void run() {while(true) {

if (counter == null) return;if (i>0) { tick(); --i; }if (i==0) { beep(); return;}

}}

Page 14: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

ThreadDemo Example (1)

Page 15: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

ThreadDemo Example (2)

Applet

ThreadDemo ThreadPanel

rotate()start()stop()

A,B

init()start()stop()

Runnable

Rotator

run()

GraphicCanvasPanel

Thread

DisplayThread

display

thread

target

rotate()

Page 16: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

ThreadDemo Example (3)

class Rotator implements Runnable {

public void run() {try {

while(true) ThreadPanel.rotate();} catch(InterruptedException e) {}

}}

Rotator implements the runnable interface,

calling ThreadPanel.rotate() to move the display

run()finishes if an exception is raised by Thread.interrupt().

Page 17: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

ThreadDemo Example (4)public class ThreadPanel extends Panel {

// construct display with title and segment color cpublic ThreadPanel(String title, Color c) {…}

// rotate display of currently running thread 6 degrees // return value not used in this example public static boolean rotate()

throws InterruptedException {…}

// create a new thread with target r and start it runningpublic void start(Runnable r) {

thread = new DisplayThread(canvas,r,…);thread.start();

}

// stop the thread using Thread.interrupt()public void stop() {Thread.interrupt();}

}

ThreadPanelmanages the display and control buttons for a thread.

Calls to rotate()are delegated to DisplayThread.

Threads are created by the start() method, and terminated by the stop() method.

Page 18: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

ThreadDemo Example (5)public class ThreadDemo extends Applet {

ThreadPanel A; ThreadPanel B;

public void init() {A = new ThreadPanel("Thread A",Color.blue);B = new ThreadPanel("Thread B",Color.blue);add(A); add(B);

}

public void start() {A.start(new Rotator());B.start(new Rotator());

}

public void stop() {A.stop();B.stop();

}}

ThreadDemo creates two ThreadPanel displays when initialized and two threads when started.

Page 19: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

What do we need for concurrency?• Process creation

– How do you specify concurrent processes?• Communication

– How do processes exchange information?• Synchronization

– How do processes maintain consistency?

Page 20: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (1)• Ornamental garden problem:

– People enter an ornamental garden through either of two turnstiles. Management wish to know how many are in the garden at any time.

• The concurrent program consists of two concurrent threads and a shared counter object.

Garden

WestTurnstile

EastTurnstile

people

Page 21: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (2)

setvalue()NumberCanvas

Applet

init()go()

Garden

Thread

Turnstile

run()

Counterincrement()

displaydisplay

east,west people

eastD,westD,counterD

The Turnstile thread simulates the periodic arrival of a visitor to the garden every second by sleeping for a second and then invoking the increment() method of the counter object.

Page 22: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (3)• The Counter object and Turnstile threads

are created by the go() method of the Garden applet:private void go() {counter = new Counter(counterD);west = new Turnstile(westD,counter);east = new Turnstile(eastD,counter);west.start();east.start();

}

Page 23: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (4)class Turnstile extends Thread {

NumberCanvas display;Counter people;

Turnstile(NumberCanvas n,Counter c){ display = n; people = c; }

public void run() {try{

display.setvalue(0);for (int i=1;i<=Garden.MAX;i++){

Thread.sleep(500); //0.5 second between arrivalsdisplay.setvalue(i);people.increment();

}} catch (InterruptedException e) {}

}}

The run() method exits and the thread terminates after Garden.MAX visitors have entered.

Page 24: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (5)class Counter {

int value=0;NumberCanvas display;

Counter(NumberCanvas n) {display=n;display.setvalue(value);

}

void increment() {int temp = value; //read valueSimulate.HWinterrupt();value=temp+1; //write valuedisplay.setvalue(value);

}}

Hardware interrupts can occur at arbitrary times.

The counter simulates a hardware interrupt during an increment(), between reading and writing to the shared counter value. Interrupt randomly calls Thread.yield() to force a thread switch.

Page 25: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (6)

• After the East and West turnstile threads have each incremented its counter 20 times, the garden people counter is not the sum of the counts displayed. Counter increments have been lost.

• Why?

Page 26: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (7)• Java method activations are not atomic -

thread objects east and west may be executing the code for the increment method at the same time.

eastwest

increment:

read value

write value + 1

programcounter program

counter

PC PCshared code

Page 27: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Interference (8)• A destructive update, caused by the

arbitrary interleaving of read and write actions, is termed interference– Interference bugs are extremely difficult to

locate• Solution: give methods mutually exclusive

access to shared objects.

Page 28: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Mutual Exclusion in Java (1)• Concurrent activations of a method in Java can be

made mutually exclusive by prefixing the method with the keyword synchronized

• We correct COUNTER class by deriving a class from it and making the increment method synchronized:

class SynchronizedCounter extends Counter {

SynchronizedCounter(NumberCanvas n) {super(n);}

synchronized void increment() {super.increment();

}}

Page 29: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Mutual Exclusion in Java (2)• Java associates a lock with every object.

– The Java compiler inserts code to acquire the lock before executing the body of the synchronized method and code to release the lock before the method returns

– Concurrent threads are blocked until the lock is released

Page 30: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Mutual Exclusion in Java (3)• Access to an object may also be made mutually

exclusive by using the synchronized statement:

• A less elegant way to correct the example would be to modify the Turnstile.run() method:

– Why is this “less elegant”?

• To ensure mutually exclusive access to an object, all object methods should be synchronized

synchronized(counter) {counter.increment();}

synchronized (object) { statements }

Page 31: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation (1)• A controller is required for a car park, which only

permits cars to enter when the car park is not full and does not permit cars to leave when there are no cars in the car park

• Car arrival and departure are simulated by separate threads

Page 32: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation (2)

Applet Runnable

ThreadPanel

CarParkControl

Arrivals

Departures

DisplayCarParkCarParkCanvas

CarParkarrivals,departures

arrive()depart()

carDisplay

carpark

disp

We have omitted DisplayThreadand GraphicCanvas threads managed by ThreadPanel.

Page 33: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation (3)• Arrivals and Departures implement Runnable, CarParkControl provides the control (condition synchronization)

• Instances of these are created by the start()method of the CarPark applet :

public void start() {CarParkControl c =

new DisplayCarPark(carDisplay,Places);arrivals.start(new Arrivals(c));departures.start(new Departures(c));

}

Page 34: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation (4)class Arrivals implements Runnable {

CarParkControl carpark;

Arrivals(CarParkControl c) {carpark = c;}

public void run() {try {

while(true) {ThreadPanel.rotate(330);carpark.arrive();ThreadPanel.rotate(30);

}} catch (InterruptedException e){}

}}

Similarly Departures which calls carpark.depart().

Page 35: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation (5)class CarParkControl {protected int spaces;protected int capacity;

CarParkControl(int n) {capacity = spaces = n;}

synchronized void arrive() {… --spaces; …}

synchronized void depart() {… ++spaces; …}

}

Mutual exclusion by synch methods

Condition synchronization?

block if full?

(spaces==0)

block if empty? (spaces==N)

Page 36: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation in Java (1)

• Java provides a thread wait queue per monitor (actually per object) with the following methods:

– Wakes up a single thread that is waiting on this object's queue.

– Wakes up all threads that are waiting on this object's queue.

– Waits to be notified by another thread. The waiting threadreleases the synchronization lock associated with the monitor. When notified, the thread must wait to reacquire the monitor before resuming execution.

public final void notify()

public final void notifyAll()

public final void wait()throws InterruptedException

Page 37: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation in Java (2)

• We refer to a thread entering a monitor when it acquires the mutual exclusion lock associated with the monitor and exiting the monitor when it releases the lock. – Wait() - causes the thread to exit the monitor,

permitting other threads to enter the monitor.

Thread A Thread B

wait()notify()

Monitor

data

Page 38: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation in Java (3)

public synchronized void act() throws InterruptedException {while (!cond) wait();// modify monitor datanotifyAll();

}

• The while loop is necessary to retest the condition cond to ensure that it is indeed satisfied when it re-enters the monitor

• notifyall() is necessary to awaken other thread(s) that may be waiting to enter the monitor now that the monitor data has been changed

Page 39: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Condition Synchronisation in Java (4)

class CarParkControl {

protected int spaces; protected int capacity;

CarParkControl(int n)

{capacity = spaces = n;}

synchronized void arrive()

throws InterruptedException

{ while (spaces==0) wait(); --spaces; notify();}

synchronized void depart()

throws InterruptedException

{ while (spaces==capacity) wait(); ++spaces;

notify(); }

}

Page 40: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Monitor Model• Active entities (that initiate actions) are implemented

as threads• Passive entities (that respond to actions) are

implemented as monitors• Each guarded action in the model of a monitor is

implemented as a synchronized method which uses a while loop and wait() to implement the guard– The while loop condition is the negation of the model

guard condition

• Changes in the state of the monitor are signalled to waiting threads using notify() or notifyAll()

Page 41: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Summary of the main points (1)• Thread construction

– Extend Thread class– Implement Runnable

• Thread activation – start()• Thread suspension (i.e. Non-Runnable)

– sleep(), yield() – and interrupt() – affects blocking and should be handled

with care!• Thread termination

– Use Thread variable, initialise to the current thread, set to null when termination is required

– Run method keeps on checking the value of the Thread variable (use Thread.currentThread())

– Thread.interrupt()

Page 42: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Summary of the main points (2)• Interference: a destructive update, caused

by the arbitrary interleaving of read and write actions– Solution: give methods mutually exclusive

access to shared objects.• Mutual exclusion in Java

– In method activations using the keyword synchronized

– Using the synchronised statement:

– Java associates a lock with every object.synchronized (object) { statements }

Page 43: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Summary of the main points (3)• An object’s lock is acquired when:

– We call an synchronised method– We enter a synchronisation block, synchronised

on the object• Monitors in Java

– Java provides a thread wait queue per object with the following methods:public final void notify()

public final void notifyAll()

public final void wait()throws InterruptedException

Page 44: Java and Concurrency CIT ConcurrencyCIT Concurrency Mutual Exclusion in Java (2) • Java associates a lock with every object. – The Java compiler inserts code to acquire the lock

CIT

Con

curr

ency

Summary of the main points (4)• Models

– Active entities as threads, passive entities as monitors

– Each guarded action as a synchronized method with a while loop and wait() to implement the guard

– Changes in the state of the monitor are signalled to waiting threads using notify()or notifyAll()