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