not (waiters > 0 and resources > 0) .
class CountingSemaphore
private Mutex mtx(false), waitq(false)
private int count, waiters = 0
Semaphore(int count) { this.count = count }
void down() throws InterruptedException
mtx.lock()
while count < 1
waiters++
mtx.unlock()
try { waitq.lock() }
catch (InterruptedException ie)
synchronized (this) { waiters-- } ; throw ie
try mtx.lock()
catch (InterruptedException ie)
synchronized (this) { waiters-- } ; throw ie
waiters--
count--
mtx.unlock()
void up()
try mtx.lock()
catch (InterruptedException ie) return
count++
if (waiters > 0) waitq.unlock()
mtx.unlock()
class Latch
// Invariant: ready -> waiters = 0
private boolean ready = false
synchronized void block()
throws InterruptedException
try { while (!ready) wait() }
catch (InterruptedException ie)
throw ie
void unblock()
if !ready
ready = true
notifyAll()
block() must be synchronized. Why?
void block() while (!ready) yield()
class Exchanger
private Object fst, snd
private boolean interrupted = false
synchronized Object exchange(Object o)
throws InterruptedException
if interrupted
interrupted = false
throw new InterruptedException()
if fst != null
snd = o
notify()
return fst
fst = o
try { while (snd == null) wait() }
catch (InterruptedException ie)
fst = snd = null
interrupted = true
throw ie
return snd
class Producer
extends Runnable
private Exchanger exch
private Buffer b
public void run()
while true
fill_buffer(b)
b = exch.exchange(b)
class Consumer
extends Runnable
private Exchanger exch
private Buffer b
public void run()
while true
b = exch.exchange(b)
empty_buffer(b)
Class ProducerConsumer
public static void main()
Exchanger exch = new Exchanger
Producer p = new Producer(exch)
Consumer p = new Consumer(exch)
class NSlotBuffer
private final boolean Full = false
private final boolean Empty = true
private final Object[] buffer = new Object[N]
synchronized public void put(Object o)
while full wait()
// Add o to the buffer.
full = buffer.size == N
empty = false
notifyAll()
synchronized public Object get()
while empty wait()
// Take o from the buffer.
empty = buffer.size == 0
full = false
notifyAll()
return o
class ConditionVariable
private final Mutex mutex
ConditionalVariable(Mutex lock) { mutex = lock }
public void pause()
public boolean tryPause(long delay)
public void proceed()
public void proceedAll()
class NSlotBuffer
private final Mutex mutex = new Mutex()
private final CondVar notFull = new CondVar(mutex)
private final CondVar notEmpty = new CondVar(mutex)
private final Object[] buffer = new Object[N]
public void put(Object o)
mutex.lock()
try
while (buffer full) notFull.pause()
// Add o to the buffer.d
notEmpty.proceed()
finally mutex.unlock()
public Object get()
mutex.lock()
try
while (buffer empty) notEmpty.pause()
// Take o from the buffer.
notFull.proceed()
finally mutex.unlock()
return o
public class ConditionVariable
public void pause() throws InterruptedException
if Thread.interrupted()
throw new InterruptedException()
try
synchronized this
mutex.unlock() // It's locked coming in.
try wait()
catch (InterruptedException ex)
notify()
throw ex
finally
boolean interrupted = false
while true
try
mutex.lock()
break
catch (InterruptedException ex)
interrupted = true
if interrupted
Thread.currentThread().interrupt()
public synchronized void proceed()
notify()
This page last modified on 16 July 2003.