ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/FutureTask.java (file contents):
Revision 1.2 by dl, Tue May 27 18:14:40 2003 UTC vs.
Revision 1.3 by dl, Tue Jun 3 16:44:36 2003 UTC

# Line 35 | Line 35 | package java.util.concurrent;
35   * @revised $Date$
36   * @editor $Author$
37   */
38 < public class FutureTask<V> implements Cancellable, Future<V>, Runnable {
39 <    private V result;
40 <    private Throwable exception;
41 <    private boolean ready;
42 <    private Thread runner;
43 <    private final Callable<V> callable;
44 <    private boolean cancelled;
45 <    private final ReentrantLock lock = new ReentrantLock();
46 <    private final Condition accessible = lock.newCondition();
38 > public class FutureTask<V> extends CancellableTask implements Cancellable, Future<V>, Runnable {
39  
40      /**
41       * Constructs a <tt>FutureTask</tt> that will upon running, execute the
# Line 52 | Line 44 | public class FutureTask<V> implements Ca
44       * @param  callable the callable task
45       */
46      public FutureTask(Callable<V> callable) {
47 <        this.callable = callable;
47 >        // must set after super ctor call to use inner class
48 >        super();
49 >        setRunnable(new InnerCancellableFuture(callable));
50      }
51  
52      /**
# Line 66 | Line 60 | public class FutureTask<V> implements Ca
60       * <tt>Boolean.TRUE</tt>.
61       */
62      public FutureTask(final Runnable runnable, final V result) {
63 <        callable = new Callable<V>() {
64 <            public V call() {
65 <                runnable.run();
66 <                return result;
67 <            }
68 <        };
69 <    }
70 <
77 <    /* Runnable implementation. */
78 <
79 <    /** Starts the computation. */
80 <    public void run() {
81 <        doRun();
63 >        super();
64 >        setRunnable(new InnerCancellableFuture
65 >                    (new Callable<V>() {
66 >                        public V call() {
67 >                            runnable.run();
68 >                            return result;
69 >                        }
70 >                    }));
71      }
72  
73      /**
85     * Executes the callable if not already cancelled or running, and
86     * sets the value or exception with its results.
87     */
88    protected void doRun() {
89        try {
90            lock.lock();
91            try {
92                if (ready || runner != null)
93                    return;
94                runner = Thread.currentThread();
95            }
96            finally {
97                lock.unlock();
98            }
99            set(callable.call());
100        }
101        catch(Throwable ex) {
102            setException(ex);
103        }
104    }
105
106    /* Future implementation. INHERIT this javadoc from interface??? Note CancellationException. */
107
108    /**
74       * Waits if necessary for the computation to complete, and then retrieves
75       * its result.
76       *
# Line 116 | Line 81 | public class FutureTask<V> implements Ca
81       * @throws InterruptedException if current thread was interrupted while waiting
82       */
83      public V get() throws InterruptedException, ExecutionException {
84 <        lock.lock();
120 <        try {
121 <            while (!ready)
122 <                accessible.await();
123 <            if (cancelled)
124 <                throw new CancellationException();
125 <            else if (exception != null)
126 <                throw new ExecutionException(exception);
127 <            else
128 <                return result;
129 <        }
130 <        finally {
131 <            lock.unlock();
132 <        }
84 >        return ((InnerCancellableFuture<V>)getRunnable()).get();
85      }
86  
87      /**
# Line 147 | Line 99 | public class FutureTask<V> implements Ca
99       */
100      public V get(long timeout, TimeUnit unit)
101          throws InterruptedException, ExecutionException, TimeoutException {
102 <
151 <        lock.lock();
152 <        try {
153 <            if (!ready) {
154 <                long nanos = unit.toNanos(timeout);
155 <                do {
156 <                    if (nanos <= 0)
157 <                        throw new TimeoutException();
158 <                    nanos = accessible.awaitNanos(nanos);
159 <                } while (!ready);
160 <            }
161 <            if (cancelled)
162 <                throw new CancellationException();
163 <            else if (exception != null)
164 <                throw new ExecutionException(exception);
165 <            else
166 <                return result;
167 <        }
168 <        finally {
169 <            lock.unlock();
170 <        }
102 >        return ((InnerCancellableFuture<V>)getRunnable()).get(timeout, unit);
103      }
104  
105      /**
# Line 180 | Line 112 | public class FutureTask<V> implements Ca
112       * @fixme Need to clarify "should" in "should only be called once".
113       */
114      protected void set(V v) {
115 <        lock.lock();
184 <        try {
185 <            ready = true;
186 <            result = v;
187 <            runner = null;
188 <            accessible.signalAll();
189 <        }
190 <        finally {
191 <            lock.unlock();
192 <        }
115 >        ((InnerCancellableFuture<V>)getRunnable()).set(v);
116      }
117  
118      /**
# Line 201 | Line 124 | public class FutureTask<V> implements Ca
124       * @param t the throwable
125       */
126      protected void setException(Throwable t) {
127 <        lock.lock();
205 <        try {
206 <            ready = true;
207 <            exception = t;
208 <            runner = null;
209 <            accessible.signalAll();
210 <        }
211 <        finally {
212 <            lock.unlock();
213 <        }
214 <    }
215 <
216 <    /* Cancellable implementation. */
217 <
218 <    public boolean cancel(boolean mayInterruptIfRunning) {
219 <        lock.lock();
220 <        try {
221 <            if (ready || cancelled)
222 <                return false;
223 <            if (mayInterruptIfRunning &&
224 <                runner != null && runner != Thread.currentThread())
225 <                runner.interrupt();
226 <            return cancelled = ready = true;
227 <        }
228 <        finally {
229 <            lock.unlock();
230 <        }
231 <    }
232 <
233 <    public boolean isCancelled() {
234 <        lock.lock();
235 <        try {
236 <            return cancelled;
237 <        }
238 <        finally {
239 <            lock.unlock();
240 <        }
241 <    }
242 <
243 <    public boolean isDone() {
244 <        lock.lock();
245 <        try {
246 <            return ready;
247 <        }
248 <        finally {
249 <            lock.unlock();
250 <        }
127 >        ((InnerCancellableFuture<V>)getRunnable()).setException(t);
128      }
129 +
130   }
131  
132  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines