01: package com.knowgate.multithreating;
02:
03: //-< Semaphore.java >------------------------------------------------*--------*
04: // JSYNC Version 1.04 (c) 1998 GARRET * ? *
05: // (Java synchronization classes) * /\| *
06: // * / \ *
07: // Created: 20-Jun-98 K.A. Knizhnik * / [] \ *
08: // Last update: 10-Jul-98 K.A. Knizhnik * GARRET *
09: // http://www.garret.ru/~knizhnik/java.html *
10: //-------------------------------------------------------------------*--------*
11: // Simple semaphore with wait() signal() operations
12: //-------------------------------------------------------------------*--------*
13:
14: /** Classical Dijkstra semaphore with <code>wait()</code> and
15: * <code>signal()</code> operations.
16: * @author Konstantin Knizhnik
17: * @version 1.04
18: */
19:
20: public final class Semaphore {
21: /** Wait for non-zero value of counter.
22: */
23: public synchronized void waitSemaphore()
24: throws InterruptedException {
25: while (counter == 0) {
26: try {
27: wait();
28: } catch (InterruptedException ex) {
29: // It is possible for a thread to be interrupted after
30: // being notified but before returning from the wait()
31: // call. To prevent lost of notification notify()
32: // is invoked.
33: notify();
34: throw new InterruptedException("Thread was interrupted");
35: }
36: }
37: counter -= 1;
38: }
39:
40: /** Wait at most <code>timeout</code> miliseconds for non-zero value
41: * of counter.
42: *
43: * @param timeout the maximum time to wait in milliseconds.
44: * @return <code>true</code> if counter is not zero, <code>false</code>
45: * if <code>wait()</code> was terminated due to timeout expiration.
46: */
47: public synchronized boolean waitSemaphore(long timeout)
48: throws InterruptedException {
49: if (counter == 0) {
50: long startTime = System.currentTimeMillis();
51: do {
52: long currentTime = System.currentTimeMillis();
53: if (currentTime - startTime >= timeout) {
54: return false;
55: }
56: try {
57: wait(timeout - currentTime + startTime);
58: } catch (InterruptedException ex) {
59: // It is possible for a thread to be interrupted after
60: // being notified but before returning from the wait()
61: // call. To prevent lost of notification notify()
62: // is invoked.
63: notify();
64: throw new InterruptedException(
65: "Thread was interrupted");
66: }
67: } while (counter == 0);
68: }
69: counter -= 1;
70: return true;
71: }
72:
73: /** Increment value of the counter. If there are waiting threads, exactly
74: * one of them will be awaken.
75: */
76: public synchronized void signal() {
77: counter += 1;
78: notify();
79: }
80:
81: /** Create semaphore with zero counter value.
82: */
83: public Semaphore() {
84: counter = 0;
85: }
86:
87: /** Create semaphore with specified non-negative counter value.
88: *
89: * @param initValue initial value of semaphore counter
90: */
91: public Semaphore(int initValue) {
92: counter = initValue;
93: }
94:
95: protected int counter;
96: }
|