package com.knowgate.multithreating; //-< Semaphore.java >------------------------------------------------*--------* // JSYNC Version 1.04 (c) 1998 GARRET * ? * // (Java synchronization classes) * /\| * // * / \ * // Created: 20-Jun-98 K.A. Knizhnik * / [] \ * // Last update: 10-Jul-98 K.A. Knizhnik * GARRET * // http://www.garret.ru/~knizhnik/java.html * //-------------------------------------------------------------------*--------* // Simple semaphore with wait() signal() operations //-------------------------------------------------------------------*--------* /** Classical Dijkstra semaphore with <code>wait()</code> and * <code>signal()</code> operations. * @author Konstantin Knizhnik * @version 1.04 */ public final class Semaphore { /** Wait for non-zero value of counter. */ public synchronized void waitSemaphore() throws InterruptedException { while (counter == 0) { try { wait(); } catch(InterruptedException ex) { // It is possible for a thread to be interrupted after // being notified but before returning from the wait() // call. To prevent lost of notification notify() // is invoked. notify(); throw new InterruptedException("Thread was interrupted"); } } counter -= 1; } /** Wait at most <code>timeout</code> miliseconds for non-zero value * of counter. * * @param timeout the maximum time to wait in milliseconds. * @return <code>true</code> if counter is not zero, <code>false</code> * if <code>wait()</code> was terminated due to timeout expiration. */ public synchronized boolean waitSemaphore(long timeout) throws InterruptedException { if (counter == 0) { long startTime = System.currentTimeMillis(); do { long currentTime = System.currentTimeMillis(); if (currentTime - startTime >= timeout) { return false; } try { wait(timeout - currentTime + startTime); } catch(InterruptedException ex) { // It is possible for a thread to be interrupted after // being notified but before returning from the wait() // call. To prevent lost of notification notify() // is invoked. notify(); throw new InterruptedException("Thread was interrupted"); } } while (counter == 0); } counter -= 1; return true; } /** Increment value of the counter. If there are waiting threads, exactly * one of them will be awaken. */ public synchronized void signal() { counter += 1; notify(); } /** Create semaphore with zero counter value. */ public Semaphore() { counter = 0; } /** Create semaphore with specified non-negative counter value. * * @param initValue initial value of semaphore counter */ public Semaphore(int initValue) { counter = initValue; } protected int counter; }