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.1 by tim, Wed May 14 21:30:47 2003 UTC vs.
Revision 1.2 by dl, Tue May 27 18:14:40 2003 UTC

# Line 1 | Line 1
1   /*
2 < * @(#)FutureTask.java
2 > * Written by Doug Lea with assistance from members of JCP JSR-166
3 > * Expert Group and released to the public domain. Use, modify, and
4 > * redistribute this code in any way without acknowledgement.
5   */
6  
7   package java.util.concurrent;
# Line 34 | Line 36 | package java.util.concurrent;
36   * @editor $Author$
37   */
38   public class FutureTask<V> implements Cancellable, Future<V>, Runnable {
37
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();
47  
48      /**
49       * Constructs a <tt>FutureTask</tt> that will upon running, execute the
# Line 84 | Line 87 | public class FutureTask<V> implements Ca
87       */
88      protected void doRun() {
89          try {
90 <            synchronized(this) {
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) {
# Line 108 | Line 115 | public class FutureTask<V> implements Ca
115       * @throws ExecutionException if the underlying computation threw an exception
116       * @throws InterruptedException if current thread was interrupted while waiting
117       */
118 <    public synchronized V get() throws InterruptedException, ExecutionException {
119 <        while (!ready)
120 <            wait();
121 <        if (cancelled)
122 <            throw new CancellationException();
123 <        else if (exception != null)
124 <            throw new ExecutionException(exception);
125 <        else
126 <            return result;
118 >    public V get() throws InterruptedException, ExecutionException {
119 >        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 >        }
133      }
134  
135      /**
# Line 124 | Line 137 | public class FutureTask<V> implements Ca
137       * complete, and then retrieves its result.
138       *
139       * @param timeout the maximum time to wait
140 <     * @param granularity the time unit of the timeout argument
140 >     * @param unit the time unit of the timeout argument
141       * @return value of this task
142       * @throws CancellationException if task producing this value was cancelled before completion
143       * @throws ExecutionException if the underlying computation
# Line 132 | Line 145 | public class FutureTask<V> implements Ca
145       * @throws InterruptedException if current thread was interrupted while waiting
146       * @throws TimeoutException if the wait timed out
147       */
148 <    public synchronized V get(long timeout, TimeUnit granularity)
148 >    public V get(long timeout, TimeUnit unit)
149          throws InterruptedException, ExecutionException, TimeoutException {
150  
151 <        if (!ready) {
152 <            long startTime = TimeUnit.highResolutionTime();
153 <            long waitTime = timeout;
154 <            for (;;) {
155 <                granularity.timedWait(this, waitTime);
156 <                if (ready)
144 <                    break;
145 <                else {
146 <                    waitTime = TimeUnit.highResolutionTime() - startTime;
147 <                    if (waitTime <= 0)
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 <                }
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          }
152        if (cancelled)
153            throw new CancellationException();
154        else if (exception != null)
155            throw new ExecutionException(exception);
156        else
157            return result;
171      }
172  
173      /**
# Line 166 | Line 179 | public class FutureTask<V> implements Ca
179       *
180       * @fixme Need to clarify "should" in "should only be called once".
181       */
182 <    protected synchronized void set(V v) {
183 <        ready = true;
184 <        result = v;
185 <        runner = null;
186 <        notifyAll();
182 >    protected void set(V v) {
183 >        lock.lock();
184 >        try {
185 >            ready = true;
186 >            result = v;
187 >            runner = null;
188 >            accessible.signalAll();
189 >        }
190 >        finally {
191 >            lock.unlock();
192 >        }
193      }
194  
195      /**
# Line 181 | Line 200 | public class FutureTask<V> implements Ca
200       *
201       * @param t the throwable
202       */
203 <    protected synchronized void setException(Throwable t) {
204 <        ready = true;
205 <        exception = t;
206 <        runner = null;
207 <        notifyAll();
203 >    protected void setException(Throwable t) {
204 >        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 synchronized boolean cancel(boolean mayInterruptIfRunning) {
219 <        if (ready || cancelled)
220 <            return false;
221 <        if (mayInterruptIfRunning &&
222 <            runner != null && runner != Thread.currentThread())
223 <            runner.interrupt();
224 <        return cancelled = ready = true;
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 synchronized boolean isCancelled() {
234 <        return cancelled;
233 >    public boolean isCancelled() {
234 >        lock.lock();
235 >        try {
236 >            return cancelled;
237 >        }
238 >        finally {
239 >            lock.unlock();
240 >        }
241      }
242  
243 <    public synchronized boolean isDone() {
244 <        return ready;
243 >    public boolean isDone() {
244 >        lock.lock();
245 >        try {
246 >            return ready;
247 >        }
248 >        finally {
249 >            lock.unlock();
250 >        }
251      }
252   }
253  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines