KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > util > internal > concurrent > WaitQueue


1 /*
2   based on file: QueuedSemaphore.java
3   Originally written by Doug Lea and released into the public domain.
4   This may be used for any purposes whatsoever without acknowledgment.
5   Thanks for the assistance and support of Sun Microsystems Labs,
6   and everyone contributing, testing, and using this code.
7   History:
8   Date Who What
9   11Jun1998 dl Create public version
10    5Aug1998 dl replaced int counters with longs
11   24Aug1999 dl release(n): screen arguments
12  */

13
14 package org.apache.beehive.netui.util.internal.concurrent;
15
16 import java.util.*;
17
18 /**
19  * Base class for internal queue classes for semaphores, etc.
20  * Relies on subclasses to actually implement queue mechanics.
21  * NOTE: this class is NOT present in java.util.concurrent.
22  **/

23
24 abstract class WaitQueue {
25
26     public abstract void insert(WaitNode w); // assumed not to block
27
public abstract WaitNode extract(); // should return null if empty
28

29     public abstract boolean hasNodes();
30     public abstract int getLength();
31     public abstract Collection getWaitingThreads();
32     public abstract boolean isWaiting(Thread JavaDoc thread);
33
34     static interface QueuedSync {
35         // invoked with sync on wait node, (atomically) just before enqueuing
36
boolean recheck(WaitNode node);
37         // invoked with sync on wait node, (atomically) just before signalling
38
void takeOver(WaitNode node);
39     }
40
41     static class WaitNode {
42         boolean waiting = true;
43         WaitNode next = null;
44         final Thread JavaDoc owner;
45
46         public WaitNode() {
47             this.owner = Thread.currentThread();
48         }
49
50         public Thread JavaDoc getOwner() {
51             return owner;
52         }
53
54         public synchronized boolean signal(QueuedSync sync) {
55             boolean signalled = waiting;
56             if (signalled) {
57                 waiting = false;
58                 notify();
59                 sync.takeOver(this);
60             }
61             return signalled;
62         }
63
64         public synchronized boolean doTimedWait(QueuedSync sync, long nanos)
65             throws InterruptedException JavaDoc
66         {
67             if (sync.recheck(this) || !waiting)
68                 return true;
69             else if (nanos <= 0) {
70                 waiting = false;
71                 return false;
72             }
73             else {
74                 long deadline = Utils.nanoTime() + nanos;
75                 try {
76                     for (; ; ) {
77                         TimeUnit.NANOSECONDS.timedWait(this, nanos);
78                         if (!waiting) // definitely signalled
79
return true;
80                         else {
81                             nanos = deadline - Utils.nanoTime();
82                             if (nanos <= 0) { // timed out
83
waiting = false;
84                                 return false;
85                             }
86                         }
87                     }
88                 }
89                 catch (InterruptedException JavaDoc ex) {
90                     if (waiting) { // no notification
91
waiting = false; // invalidate for the signaller
92
throw ex;
93                     }
94                     else { // thread was interrupted after it was notified
95
Thread.currentThread().interrupt();
96                         return true;
97                     }
98                 }
99             }
100         }
101
102         public synchronized void doWait(QueuedSync sync)
103             throws InterruptedException JavaDoc
104         {
105             if (!sync.recheck(this)) {
106                 try {
107                     while (waiting) wait();
108                 }
109                 catch (InterruptedException JavaDoc ex) {
110                     if (waiting) { // no notification
111
waiting = false; // invalidate for the signaller
112
throw ex;
113                     }
114                     else { // thread was interrupted after it was notified
115
Thread.currentThread().interrupt();
116                         return;
117                     }
118                 }
119             }
120         }
121     }
122
123 }
124
125
Popular Tags