Mercurial > hg > blitz_condensed
comparison src/EDU/oswego/cs/dl/util/concurrent/CountDown.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3dc0c5604566 |
---|---|
1 /* | |
2 File: CountDown.java | |
3 | |
4 Originally written by Doug Lea and released into the public domain. | |
5 This may be used for any purposes whatsoever without acknowledgment. | |
6 Thanks for the assistance and support of Sun Microsystems Labs, | |
7 and everyone contributing, testing, and using this code. | |
8 | |
9 History: | |
10 Date Who What | |
11 11Jun1998 dl Create public version | |
12 */ | |
13 | |
14 package EDU.oswego.cs.dl.util.concurrent; | |
15 | |
16 /** | |
17 * A CountDown can serve as a simple one-shot barrier. | |
18 * A Countdown is initialized | |
19 * with a given count value. Each release decrements the count. | |
20 * All acquires block until the count reaches zero. Upon reaching | |
21 * zero all current acquires are unblocked and all | |
22 * subsequent acquires pass without blocking. This is a one-shot | |
23 * phenomenon -- the count cannot be reset. | |
24 * If you need a version that resets the count, consider | |
25 * using a Barrier. | |
26 * <p> | |
27 * <b>Sample usage.</b> Here are a set of classes in which | |
28 * a group of worker threads use a countdown to | |
29 * notify a driver when all threads are complete. | |
30 * <pre> | |
31 * class Worker implements Runnable { | |
32 * private final CountDown done; | |
33 * Worker(CountDown d) { done = d; } | |
34 * public void run() { | |
35 * doWork(); | |
36 * done.release(); | |
37 * } | |
38 * } | |
39 * | |
40 * class Driver { // ... | |
41 * void main() { | |
42 * CountDown done = new CountDown(N); | |
43 * for (int i = 0; i < N; ++i) | |
44 * new Thread(new Worker(done)).start(); | |
45 * doSomethingElse(); | |
46 * done.acquire(); // wait for all to finish | |
47 * } | |
48 * } | |
49 * </pre> | |
50 * | |
51 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] | |
52 * | |
53 **/ | |
54 | |
55 public class CountDown implements Sync { | |
56 protected final int initialCount_; | |
57 protected int count_; | |
58 | |
59 /** Create a new CountDown with given count value **/ | |
60 public CountDown(int count) { count_ = initialCount_ = count; } | |
61 | |
62 | |
63 /* | |
64 This could use double-check, but doesn't out of concern | |
65 for surprising effects on user programs stemming | |
66 from lack of memory barriers with lack of synch. | |
67 */ | |
68 public void acquire() throws InterruptedException { | |
69 if (Thread.interrupted()) throw new InterruptedException(); | |
70 synchronized(this) { | |
71 while (count_ > 0) | |
72 wait(); | |
73 } | |
74 } | |
75 | |
76 | |
77 public boolean attempt(long msecs) throws InterruptedException { | |
78 if (Thread.interrupted()) throw new InterruptedException(); | |
79 synchronized(this) { | |
80 if (count_ <= 0) | |
81 return true; | |
82 else if (msecs <= 0) | |
83 return false; | |
84 else { | |
85 long waitTime = msecs; | |
86 long start = System.currentTimeMillis(); | |
87 for (;;) { | |
88 wait(waitTime); | |
89 if (count_ <= 0) | |
90 return true; | |
91 else { | |
92 waitTime = msecs - (System.currentTimeMillis() - start); | |
93 if (waitTime <= 0) | |
94 return false; | |
95 } | |
96 } | |
97 } | |
98 } | |
99 } | |
100 | |
101 /** | |
102 * Decrement the count. | |
103 * After the initialCount'th release, all current and future | |
104 * acquires will pass | |
105 **/ | |
106 public synchronized void release() { | |
107 if (--count_ == 0) | |
108 notifyAll(); | |
109 } | |
110 | |
111 /** Return the initial count value **/ | |
112 public int initialCount() { return initialCount_; } | |
113 | |
114 | |
115 /** | |
116 * Return the current count value. | |
117 * This is just a snapshot value, that may change immediately | |
118 * after returning. | |
119 **/ | |
120 public synchronized int currentCount() { return count_; } | |
121 } | |
122 |