Mercurial > hg > blitz_stable
comparison src/EDU/oswego/cs/dl/util/concurrent/FutureResult.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: FutureResult.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 30Jun1998 dl Create public version | |
12 */ | |
13 | |
14 package EDU.oswego.cs.dl.util.concurrent; | |
15 import java.lang.reflect.*; | |
16 | |
17 /** | |
18 * A class maintaining a single reference variable serving as the result | |
19 * of an operation. The result cannot be accessed until it has been set. | |
20 * <p> | |
21 * <b>Sample Usage</b> <p> | |
22 * <pre> | |
23 * class ImageRenderer { Image render(byte[] raw); } | |
24 * class App { | |
25 * Executor executor = ... | |
26 * ImageRenderer renderer = ... | |
27 * void display(byte[] rawimage) { | |
28 * try { | |
29 * FutureResult futureImage = new FutureResult(); | |
30 * Runnable command = futureImage.setter(new Callable() { | |
31 * public Object call() { return renderer.render(rawImage); } | |
32 * }); | |
33 * executor.execute(command); | |
34 * drawBorders(); // do other things while executing | |
35 * drawCaption(); | |
36 * drawImage((Image)(futureImage.get())); // use future | |
37 * } | |
38 * catch (InterruptedException ex) { return; } | |
39 * catch (InvocationTargetException ex) { cleanup(); return; } | |
40 * } | |
41 * } | |
42 * </pre> | |
43 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] | |
44 * @see Executor | |
45 **/ | |
46 | |
47 public class FutureResult { | |
48 /** The result of the operation **/ | |
49 protected Object value_ = null; | |
50 | |
51 /** Status -- true after first set **/ | |
52 protected boolean ready_ = false; | |
53 | |
54 /** the exception encountered by operation producing result **/ | |
55 protected InvocationTargetException exception_ = null; | |
56 | |
57 /** | |
58 * Create an initially unset FutureResult | |
59 **/ | |
60 public FutureResult() { } | |
61 | |
62 | |
63 /** | |
64 * Return a Runnable object that, when run, will set the result value. | |
65 * @param function - a Callable object whose result will be | |
66 * held by this FutureResult. | |
67 * @return A Runnable object that, when run, will call the | |
68 * function and (eventually) set the result. | |
69 **/ | |
70 | |
71 public Runnable setter(final Callable function) { | |
72 return new Runnable() { | |
73 public void run() { | |
74 try { | |
75 set(function.call()); | |
76 } | |
77 catch(Throwable ex) { | |
78 setException(ex); | |
79 } | |
80 } | |
81 }; | |
82 } | |
83 | |
84 /** internal utility: either get the value or throw the exception **/ | |
85 protected Object doGet() throws InvocationTargetException { | |
86 if (exception_ != null) | |
87 throw exception_; | |
88 else | |
89 return value_; | |
90 } | |
91 | |
92 /** | |
93 * Access the reference, waiting if necessary until it is ready. | |
94 * @return current value | |
95 * @exception InterruptedException if current thread has been interrupted | |
96 * @exception InvocationTargetException if the operation | |
97 * producing the value encountered an exception. | |
98 **/ | |
99 public synchronized Object get() | |
100 throws InterruptedException, InvocationTargetException { | |
101 while (!ready_) wait(); | |
102 return doGet(); | |
103 } | |
104 | |
105 | |
106 | |
107 /** | |
108 * Wait at most msecs to access the reference. | |
109 * @return current value | |
110 * @exception TimeoutException if not ready after msecs | |
111 * @exception InterruptedException if current thread has been interrupted | |
112 * @exception InvocationTargetException if the operation | |
113 * producing the value encountered an exception. | |
114 **/ | |
115 public synchronized Object timedGet(long msecs) | |
116 throws TimeoutException, InterruptedException, InvocationTargetException { | |
117 long startTime = (msecs <= 0)? 0 : System.currentTimeMillis(); | |
118 long waitTime = msecs; | |
119 if (ready_) return doGet(); | |
120 else if (waitTime <= 0) throw new TimeoutException(msecs); | |
121 else { | |
122 for (;;) { | |
123 wait(waitTime); | |
124 if (ready_) return doGet(); | |
125 else { | |
126 waitTime = msecs - (System.currentTimeMillis() - startTime); | |
127 if (waitTime <= 0) | |
128 throw new TimeoutException(msecs); | |
129 } | |
130 } | |
131 } | |
132 } | |
133 | |
134 /** | |
135 * Set the reference, and signal that it is ready. It is not | |
136 * considered an error to set the value more than once, | |
137 * but it is not something you would normally want to do. | |
138 * @param newValue The value that will be returned by a subsequent get(); | |
139 **/ | |
140 public synchronized void set(Object newValue) { | |
141 value_ = newValue; | |
142 ready_ = true; | |
143 notifyAll(); | |
144 } | |
145 | |
146 /** | |
147 * Set the exception field, also setting ready status. | |
148 * @param ex The exception. It will be reported out wrapped | |
149 * within an InvocationTargetException | |
150 **/ | |
151 public synchronized void setException(Throwable ex) { | |
152 exception_ = new InvocationTargetException(ex); | |
153 ready_ = true; | |
154 notifyAll(); | |
155 } | |
156 | |
157 | |
158 /** | |
159 * Get the exception, or null if there isn't one (yet). | |
160 * This does not wait until the future is ready, so should | |
161 * ordinarily only be called if you know it is. | |
162 * @return the exception encountered by the operation | |
163 * setting the future, wrapped in an InvocationTargetException | |
164 **/ | |
165 public synchronized InvocationTargetException getException() { | |
166 return exception_; | |
167 } | |
168 | |
169 /** | |
170 * Return whether the reference or exception have been set. | |
171 * @return true if has been set. else false | |
172 **/ | |
173 public synchronized boolean isReady() { | |
174 return ready_; | |
175 } | |
176 | |
177 /** | |
178 * Access the reference, even if not ready | |
179 * @return current value | |
180 **/ | |
181 public synchronized Object peek() { | |
182 return value_; | |
183 } | |
184 | |
185 | |
186 /** | |
187 * Clear the value and exception and set to not-ready, | |
188 * allowing this FutureResult to be reused. This is not | |
189 * particularly recommended and must be done only | |
190 * when you know that no other object is depending on the | |
191 * properties of this FutureResult. | |
192 **/ | |
193 public synchronized void clear() { | |
194 value_ = null; | |
195 exception_ = null; | |
196 ready_ = false; | |
197 } | |
198 | |
199 } | |
200 | |
201 | |
202 |