Mercurial > hg > blitz_condensed
comparison src/EDU/oswego/cs/dl/util/concurrent/Latch.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: Latch.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 latch is a boolean condition that is set at most once, ever. | |
18 * Once a single release is issued, all acquires will pass. | |
19 * <p> | |
20 * <b>Sample usage.</b> Here are a set of classes that use | |
21 * a latch as a start signal for a group of worker threads that | |
22 * are created and started beforehand, and then later enabled. | |
23 * <pre> | |
24 * class Worker implements Runnable { | |
25 * private final Latch startSignal; | |
26 * Worker(Latch l) { startSignal = l; } | |
27 * public void run() { | |
28 * startSignal.acquire(); | |
29 * doWork(); | |
30 * } | |
31 * void doWork() { ... } | |
32 * } | |
33 * | |
34 * class Driver { // ... | |
35 * void main() { | |
36 * Latch go = new Latch(); | |
37 * for (int i = 0; i < N; ++i) // make threads | |
38 * new Thread(new Worker(go)).start(); | |
39 * doSomethingElse(); // don't let run yet | |
40 * go.release(); // let all threads proceed | |
41 * } | |
42 * } | |
43 *</pre> | |
44 * [<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] <p> | |
45 **/ | |
46 | |
47 public class Latch implements Sync { | |
48 protected boolean latched_ = false; | |
49 | |
50 /* | |
51 This could use double-check, but doesn't. | |
52 If the latch is being used as an indicator of | |
53 the presence or state of an object, the user would | |
54 not necessarily get the memory barrier that comes with synch | |
55 that would be needed to correctly use that object. This | |
56 would lead to errors that users would be very hard to track down. So, to | |
57 be conservative, we always use synch. | |
58 */ | |
59 | |
60 public void acquire() throws InterruptedException { | |
61 if (Thread.interrupted()) throw new InterruptedException(); | |
62 synchronized(this) { | |
63 while (!latched_) | |
64 wait(); | |
65 } | |
66 } | |
67 | |
68 public boolean attempt(long msecs) throws InterruptedException { | |
69 if (Thread.interrupted()) throw new InterruptedException(); | |
70 synchronized(this) { | |
71 if (latched_) | |
72 return true; | |
73 else if (msecs <= 0) | |
74 return false; | |
75 else { | |
76 long waitTime = msecs; | |
77 long start = System.currentTimeMillis(); | |
78 for (;;) { | |
79 wait(waitTime); | |
80 if (latched_) | |
81 return true; | |
82 else { | |
83 waitTime = msecs - (System.currentTimeMillis() - start); | |
84 if (waitTime <= 0) | |
85 return false; | |
86 } | |
87 } | |
88 } | |
89 } | |
90 } | |
91 | |
92 /** Enable all current and future acquires to pass **/ | |
93 public synchronized void release() { | |
94 latched_ = true; | |
95 notifyAll(); | |
96 } | |
97 | |
98 } | |
99 |