Lecture 06
Lecture 06
19530-V (WS01)
Lecture 6:
Introduction to Monitors
and Semaphores
INCREMENT = (acquire->read[x:T]
->(when (x<N) write[x+1]
->release->increment->INCREMENT
)
)+{read[T],write[T]}.
||COUNTER = (INCREMENT||LOCK||VAR)@{increment}.
Abstraction Leads to Simpler Model
Minimized LTS for synchronized COUNTER process
Encapsulates state
The counter variable is no longer directly accessible
Exposes only the allowable actions
In this case, the increment action
Guarantees mutually exclusive access
Arrivals Departures
CAR PARK
ARRIVALS arrive CARPARK depart DEPARTURES
CONTROL
Car Park Model
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).
CAR PARK
ARRIVALS arrive CARPARK depart DEPARTURES
CONTROL
Slightly simplified
view of the actual
implementation
Runnable
Applet
arrivals,
departures
CarPark ThreadPanel Arrivals carpark
carDisplay
Departures
CarParkControl
arrive()
depart()
disp
CarParkCanvas DisplayCarPark
Semaphores
const Max = 3
range Int = 0..Max
SEMAPHORE(N=0) = SEMA[N],
SEMA[v:Int] = (up->SEMA[v+1]
|when(v>0) down->SEMA[v-1]),
SEMA[Max+1] = ERROR.
LTS?
Modeling Semaphores
Æ Æ Æ up
Trace to a violation
up up up
Semaphore Example
LOOP = (mutex.down->critical->mutex.up->LOOP).
||SEMADEMO = (p[1..3]:LOOP
||{p[1..3]}::mutex:SEMAPHORE(1)).
Semaphore Example
Semaphores in Java
Semaphores are
passive objects, public class Semaphore {
therefore private int value;
implemented as public Semaphore (int initial)
monitors. {value = initial;}
BUFFER(N=5) = COUNT[0],
COUNT[i:0..N]
= (when (i<N) put->COUNT[i+1]
|when (i>0) get->COUNT[i-1]
).
PRODUCER = (put->PRODUCER).
CONSUMER = (get->CONSUMER).
||BOUNDEDBUFFER = (PRODUCER
||BUFFER(5)||CONSUMER).
SemaBuffer(int size) {
this.size = size; buf = new Object[size];
full = new Semaphore(0);
empty = new Semaphore(size);
}
…
}
Alternative Bounded Buffer
empty is decremented during the put()operation, which is
blocked if empty is zero; full is decremented by the get()
operation, which is blocked if full is zero.
public synchronized void put(Object o)
throws InterruptedException {
empty.down();
buf[in] = o;
++count; in = (in+1) % size;
full.up();
}