Shared Objects & Mutual Exclusion
Total Page:16
File Type:pdf, Size:1020Kb
Chapter 4 Shared Objects & Mutual Exclusion Shared Objects & Concepts: process interference. Mutual Exclusion mutual exclusion and locks. Models: model checking for interference modelling mutual exclusion Practice: thread interference in shared Java objects mutual exclusion in Java (synchronized objects/methods). 1 2 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition A Concert Hall Booking System Concert Hall Booking System const False = 0 A central computer connected to remote terminals via communication links const True = 1 is used to automate seat reservations for a concert hall. range Bool = False..True To book a seat, a client chooses a free seat and the clerk enters the number SEAT = SEAT[False], of the chosen seat at the terminal and issues a ticket, if it is free. SEAT[reserved:Bool] = ( when (!reserved) reserve -> SEAT[True] A system is required which avoids double bookings of the same seat whilst | query[reserved] -> SEAT[reserved] allowing clients free choice of the available seats. | when (reserved) reserve -> ERROR //error of reserved twice Construct an abstract model of the system and demonstrate that your model does ). not permit double bookings. Like STOP, ERROR range Seats = 1..2 is a predefined FSP ||SEATS = (seat[Seats]:SEAT). local process (state), numbered -1 in the 3 equivalent LTS. 4 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition Concert Hall Booking System Concert Hall Booking System – no interference? LOCK = (acquire -> release -> LOCK). TERMINAL = (choose[s:Seats] //lock for the booking system -> seat[s].query[reserved:Bool] -> if (!reserved) then TERMINAL = (choose[s:Seats] -> acquire (seat[s].reserve -> TERMINAL) -> seat[s].query[reserved:Bool] else -> if (!reserved) then TERMINAL (seat[s].reserve -> release-> TERMINAL) ). else (release -> TERMINAL) set Terminals = {a,b} ). ||CONCERT = ( Terminals:TERMINAL || Terminals::SEATS ). set Terminals = {a,b} ||CONCERT = (Terminals:TERMINAL || Terminals::SEATS Does this system allow double booking of a seat? || Terminals::LOCK). 5 Would locking at the seat level permit more concurrency? 6 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 4.1 Interference ornamental garden Program - class diagram Ornamental garden problem: Apple t Thread People enter an ornamental garden through either of two turnstiles. Management wish to know how many are in the garden east,west Turnstile people Counter at any time. Garden Garden init() run() increment() go() eastD, display display West people East westD, NumberCanvas counterD Turnstile Turnstile setvalue() The Turnstile thread simulates the periodic arrival of a visitor to The concurrent program consists of two concurrent threads and a the garden every second by sleeping for a second and then invoking shared counter object. the increment() method of the counter object. 7 8 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition ornamental garden program Turnstile class The Counter object and Turnstile threads are created by the class Turnstile extends Thread { NumberCanvas display; go() method of the Garden applet: Counter people; The run() private void go() { Turnstile(NumberCanvas n,Counter c) method exits counter = new Counter(counterD); { display = n; people = c; } and the thread terminates after west = new Turnstile(westD,counter); public void run() { Garden.MAX east = new Turnstile(eastD,counter); try{ visitors have west.start(); display.setvalue(0); entered. east.start(); for (int i=1;i<=Garden.MAX;i++){ Thread.sleep(500); //0.5 second between arrivals } display.setvalue(i); people.increment(); Note that counterD, westD and eastD are objects of } NumberCanvas used in chapter 2. } catch (InterruptedException e) {} } 9 } 10 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition Counter class ornamental garden program - display class Counter { int value=0; NumberCanvas display; Counter(NumberCanvas n) { Hardware interrupts can occur display=n; at arbitrary times. display.setvalue(value); } The counter simulates a hardware interrupt during an void increment() { increment(), between int temp = value; //read value reading and writing to the Simulate.HWinterrupt(); shared counter value. value=temp+1; //write value Interrupt randomly calls After the East and West turnstile threads have each incremented display.setvalue(value); Thread.sleep() to force its counter 20 times, the garden people counter is not the sum } a thread switch. of the counts displayed. Counter increments have been lost. } Why? 11 12 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition concurrent method activation ornamental garden Model go Java method activations are not atomic - thread objects east go end GARDEN and west may be executing the code for the increment method end arrive at the same time. value east: value:VAR TURNSTILE display read go west write shared code east end PC arrive value PC increment: west: program TURNSTILE counter program read value counter Process VAR models read and write access to the shared counter value. write value + 1 Increment is modeled inside TURNSTILE since Java method activations are not atomic i.e. thread objects east and west may interleave their read and write actions. 13 14 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition ornamental garden model checking for errors - animation const N = 4 range T = 0..N The alphabet of shared Scenario checking - set VarAlpha = { value.{read[T],write[T]} } process VAR is declared use animation to explicitly as a set produce a trace. VAR = VAR[0], constant, VarAlpha. VAR[u:T] = (read[u] ->VAR[u] |write[v:T]->VAR[v]). The TURNSTILE TURNSTILE = (go -> RUN), alphabet is extended Is this trace RUN = (arrive-> INCREMENT with VarAlpha to correct? |end -> TURNSTILE), ensure no unintended INCREMENT = (value.read[x:T] free (autonomous) -> value.write[x+1]->RUN )+VarAlpha. actions in VAR such as value.write[0]. ||GARDEN = (east:TURNSTILE || west:TURNSTILE || { east,west,display}::value:VAR) All actions in the /{ go /{ east,west} .go, shared must be end/{ east,west} .end} . VAR controlled (shared) by 15 16 2015 Concurrency: shared objects & mutual exclusion a TURNSTILE©Magee/Kramer 2nd Edition. 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition checking for errors - exhaustive analysis ornamental garden model - checking for errors Exhaustive checking - compose the model with a TEST process which ||TESTGARDEN = (GARDEN || TEST). sums the arrivals and checks against the display value: Use LTSA to perform an exhaustive search for ERROR. Trace to property violation in TEST: TEST = TEST[0], go TEST[v:T] = east.arrive (when (v<N){east.arrive,west.arrive}->TEST[v+1] east.value.read.0 |end->CHECK[v] west.arrive ), west.value.read.0 CHECK[v:T] = Like STOP, ERROR east.value.write.1 LTSA produces the (display.value.read[u:T] -> is a predefined FSP west.value.write.1 shortest path to (when (u==v) right -> TEST[v] local process (state), end reach ERROR. |when (u!=v) wrong -> ERROR numbered -1 in the display.value.read.1 ) equivalent LTS. wrong )+{display.VarAlpha}. 17 18 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition Interference and Mutual Exclusion (mutex) 4.2 Mutual exclusion in Java Concurrent activations of a method in Java can be made Destructive update, caused by the arbitrary interleaving of mutually exclusive by prefixing the method with the keyword read and write actions, is termed interference. synchronized, which uses a lock on the object. We correct COUNTER class by deriving a class from it and making the increment method synchronized: Interference bugs are extremely difficult to locate. The class SynchronizedCounter extends Counter { general solution is to give methods mutually exclusive access to shared objects. Mutual exclusion (often referred SynchronizedCounter(NumberCanvas n) acquire {super(n);} lock to as “mutex”)can be modeled as atomic actions. synchronized void increment() { super.increment(); release } lock } 19 20 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition 2015 Concurrency: shared objects & mutual exclusion ©Magee/Kramer 2nd Edition mutual exclusion - the ornamental garden Java synchronized statement Access to an object may also be made mutually exclusive by using the synchronized statement: synchronized (object) { statements } A less elegant way to correct the example would be to modify the Turnstile.run() method: synchronized(people) {people.increment();} Why is this less elegant? 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 To ensure mutually exclusive access to an object, method returns. Concurrent threads are blocked until the lock is all object methods