COMP31212: Concurrency Topics 4.1: Concurrency Patterns - Monitors - - PowerPoint PPT Presentation

comp31212 concurrency
SMART_READER_LITE
LIVE PREVIEW

COMP31212: Concurrency Topics 4.1: Concurrency Patterns - Monitors - - PowerPoint PPT Presentation

Topic 4.1: Concurrency Patterns: Monitors COMP31212: Concurrency Topics 4.1: Concurrency Patterns - Monitors Topic 4.1: Concurrency Patterns: Monitors Outline Topic 4.1: Concurrency Patterns: Monitors Monitors FSP Models-to-Java Monitors


slide-1
SLIDE 1

Topic 4.1: Concurrency Patterns: Monitors

COMP31212: Concurrency

Topics 4.1: Concurrency Patterns - Monitors

slide-2
SLIDE 2

Topic 4.1: Concurrency Patterns: Monitors

Outline

Topic 4.1: Concurrency Patterns: Monitors Monitors FSP Models-to-Java Monitors Producers/Consumers

slide-3
SLIDE 3

Topic 4.1: Concurrency Patterns: Monitors

Monitors

Monitors are data structures with an interface which allows controlled access for multiple processes. Edsger Dijkstra Per Brinch Hansen Sir Tony Hoare

slide-4
SLIDE 4

Topic 4.1: Concurrency Patterns: Monitors

Papers

  • Cooperating Sequential Processes. E.W. Dijkstra. In

Programming Languages. Academic Press, New York. 1968.

  • Structured Multiprogramming. Per Brinch Hansen.

Communications of A.C.M. 15:7 (1972).

  • Monitors: An Operating System Structuring Concept. C.A.R.
  • Hoare. Communications of A.C.M. 17:10 (1974).
  • Java’s Insecure Parallelism. Per Brinch Hansen. SIGPLAN

Notices 34: 4 (1999).

slide-5
SLIDE 5

Topic 4.1: Concurrency Patterns: Monitors

Monitors: access control

For sequential systems access is controlled through an interface of function names/procedures/methods and their types. For concurrent systems we need sequential access control, plus:

  • Restrictions on the numbers and kinds of processes that can

have simultaneous access to the data, so called “mutual exclusion”, and

  • Job scheduling - determining which processes have access and

when, using queues, activations, and priorities. Monitors are both an implementation technique and also (in some languages) a syntactic construct which allows secure multiprogramming with simple proof rules.

slide-6
SLIDE 6

Topic 4.1: Concurrency Patterns: Monitors

Monitor scheme Process 1 Process 2 Process 3 . . . . . . Active elements Passive element Data structure Access control: Mutual exclusion and process scheduling

slide-7
SLIDE 7

Topic 4.1: Concurrency Patterns: Monitors

Variety of monitor schemes

There is a variety of monitor schemes, depending on (1) how processes requesting access are organised, (2) how ‘conditional waits’ and process suspension are handled, (3) how processes are reactivated after suspension, and (4) how process access is prioritised.

  • Some schemes have a single queue of processes requesting

access to a data structure, combining those that request access with those that have suspended processing.

  • Some schemes have two queues - new requests, and another

for all suspended processes, and then new accesses have to choose between them.

  • Some schemes allow explicit “wait on a condition”. In this

case all those waiting on a given (named) condition may be put in the same queue, so there are many queues of suspended processes, one for each condition. How are processes reactivated? Several schemes are available.

slide-8
SLIDE 8

Topic 4.1: Concurrency Patterns: Monitors

Monitors and Java implementation

Java does not have explicit monitors (in this sense), but does allow us to implement monitors (this is seen, by some, as a failure in language design).

  • Passive shared objects, methods invoked by (active) threads
  • synchronized methods to exclusively access private

variables.

  • Condition Synchronization: guarded execution:
  • looped guard-test containing wait()
  • notify()/notifyAll() after guard-state change
slide-9
SLIDE 9

Topic 4.1: Concurrency Patterns: Monitors

Synchronisation - I

class Monitor { private int x = 0; synchronized void addOne(int n, int delay) throws InterruptedException { System.out.println("Thread " + n + ": x is " + x); int t = x + 1; System.out.println("Thread " + n + ": t is " + t); Thread.sleep(delay); x = t; System.out.println("Thread " + n + ": x is " + x); } }

slide-10
SLIDE 10

Topic 4.1: Concurrency Patterns: Monitors

Synchronisation - II

class T extends Thread { Monitor obj; private int name, threadDelay; T(Monitor o, int n, int delay){

  • bj = o;

name = n; threadDelay = delay; } public void run(){ try {obj.addOne(name, threadDelay); } catch (InterruptedException e) {} } }

slide-11
SLIDE 11

Topic 4.1: Concurrency Patterns: Monitors

Synchronisation - III

public class MonitorExample { public static void main(String [] args) throws InterruptedException { int delay = Integer.parseInt(args[0]); Monitor m = new Monitor(); T t1 = new T(m, 1, delay); T t2 = new T(m, 2, delay/2); T t3 = new T(m, 3, delay/3); t1.start(); t2.start(); t3.start(); Thread.sleep(10); m.addOne(0, 0); } }

slide-12
SLIDE 12

Topic 4.1: Concurrency Patterns: Monitors

And what happens ... without synchronisation

$ java MonitorExample 20 Thread 1: x is 0 Thread 1: t is 1 Thread 2: x is 0 Thread 2: t is 1 Thread 3: x is 0 Thread 3: t is 1 Thread 3: x is 1 Thread 0: x is 1 Thread 0: t is 2 Thread 0: x is 2 Thread 2: x is 1 Thread 1: x is 1 $ $ java MonitorExample 30 Thread 1: x is 0 Thread 1: t is 1 Thread 2: x is 0 Thread 2: t is 1 Thread 3: x is 0 Thread 3: t is 1 Thread 0: x is 0 Thread 0: t is 1 Thread 0: x is 1 Thread 3: x is 1 Thread 2: x is 1 Thread 1: x is 1 $

slide-13
SLIDE 13

Topic 4.1: Concurrency Patterns: Monitors

And what happens ... with synchronisation

$ java MonitorExample 20 Thread 1: x is 0 Thread 1: t is 1 Thread 1: x is 1 Thread 0: x is 1 Thread 0: t is 2 Thread 0: x is 2 Thread 3: x is 2 Thread 3: t is 3 Thread 3: x is 3 Thread 2: x is 3 Thread 2: t is 4 Thread 2: x is 4 $ Thread 1 runs to completion Thread 0 runs to completion Thread 3 runs to completion Thread 2 runs to completion no matter what delay

slide-14
SLIDE 14

Topic 4.1: Concurrency Patterns: Monitors

Now with Conditional synchronisation ..

class Monitor { private int x = 0; synchronized void addOne(int n, int delay) throws InterruptedException { while (!(x==n)) wait(); System.out.println("Thread " + n + ": x is " + x); int t = x + 1; System.out.println("Thread " + n + ": t is " + t); Thread.sleep(delay); x = t; notifyAll(); System.out.println("Thread " + n + ": x is " + x); } }

slide-15
SLIDE 15

Topic 4.1: Concurrency Patterns: Monitors

And this is what happens ...

$ java MonitorExample 20 Thread 0: x is 0 Thread 0: t is 1 Thread 0: x is 1 Thread 1: x is 1 Thread 1: t is 2 Thread 1: x is 2 Thread 2: x is 2 Thread 2: t is 3 Thread 2: x is 3 Thread 3: x is 3 Thread 3: t is 4 Thread 3: x is 4 $ We will always get: Thread 0 runs to completion Thread 1 runs to completion Thread 2 runs to completion Thread 3 runs to completion no matter what delays

slide-16
SLIDE 16

Topic 4.1: Concurrency Patterns: Monitors

notifyAll() vs. notify()

Let us demonstrate the difference between notifyAll() and notify(). Reverse the order of starting the threads, i.e. t3 then t2 then t1, and use notify() instead of notifyAll(). We get the following:-

$ java MonitorExample 20 Thread 0: x is 0 Thread 0: t is 1 Thread 0: x is 1 We will always get: Thread 0 runs to completion Then the woken thread (3) hangs no matter what delay setting

Changing the start order back to t1, t2 and then t3, achieves the right effect with notify() because t1 will then be the woken thread.

slide-17
SLIDE 17

Topic 4.1: Concurrency Patterns: Monitors

FSP Models to Java Monitors

FSP:

when (guard) actionA -> P

Java:

synchronized type actionA (...) { while (!guard) { wait() ; } // Code for process P }

When guard is changed, signal with notify() Active objects initiate actions: implement as Threads Passive (shared) objects respond to actions: implement as Monitors

slide-18
SLIDE 18

Topic 4.1: Concurrency Patterns: Monitors

Producers and Consumers: the concept

  • Producers: produce items which are sent to consumer(s)
  • Consumers: receive items and process them independently
  • synchronous or buffered communication
slide-19
SLIDE 19

Topic 4.1: Concurrency Patterns: Monitors

Booth Street East Car Park — A Passive Object

slide-20
SLIDE 20

Topic 4.1: Concurrency Patterns: Monitors

FSP description

CARPARKCONTROL(N=4) = SPACES[N], SPACES[i:0..N] = (when(i>0) arrive->SPACES[i-1] |when(i<N) depart->SPACES[i+1] ). ARRIVALS = (arrive->ARRIVALS). DEPARTURES = (depart->DEPARTURES). ||CARPARK = (ARRIVALS||CARPARKCONTROL(4)||DEPARTURES).

slide-21
SLIDE 21

Topic 4.1: Concurrency Patterns: Monitors

Car Park Control Class

class CarParkControl { protected int spaces; protected int capacity; CarParkControl(int n) { capacity = spaces = n; } synchronized void arrive() throws InterruptedException { while (spaces==0) wait();

  • -spaces;

notifyAll(); } synchronized void depart() throws InterruptedException{ while (spaces==capacity) wait(); ++spaces; notifyAll(); } }

slide-22
SLIDE 22

Topic 4.1: Concurrency Patterns: Monitors

CountDown Timer - An Active Object

COUNTDOWN (N=3) = ( start -> COUNTDOWN[N]), COUNTDOWN[i:0..N]= ( when (i>0) tick -> COUNTDOWN[i-1] | when (i==0) beep -> STOP | stop -> STOP ).

slide-23
SLIDE 23

Topic 4.1: Concurrency Patterns: Monitors

Java for CountDown Timer - I

public class CountDown extends Applet implements Runnable { Thread counter; int i; final static int N = 3; AudioClip beepSound, tickSound; NumberCanvas display; public void init() {...} // Applet methods public void start() {...} // (don’t confuse with public void stop() {...} // Thread start/stop ) public void run() {...} // required by Runnable; // called by Thread counter private void tick(){...} // local private void beep(){...}

slide-24
SLIDE 24

Topic 4.1: Concurrency Patterns: Monitors

Java for CountDown Timer - II

public void start() { // method start for Applet counter = new Thread(this); i = N; counter.start(); // method start for Thread counter } public void stop() { // method stop for Applet counter = null; // (not using Thread stop method) } public void run() { while(true) { if (counter == null) return; if (i>0) { tick(); --i; } if (i==0) { beep(); return;} } }