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.