Code - Class EDU.oswego.cs.dl.util.concurrent.FutureResult


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
203

Java API By Example, From Geeks To Geeks. | Conditions of Use | About Us © 2002 - 2005, KickJava.com, or its affiliates