Advertisement
Guest User

Untitled

a guest
Dec 10th, 2013
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.84 KB | None | 0 0
  1. /*
  2.  * %W% %E%
  3.  *
  4.  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
  5.  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6.  */
  7.  
  8. package java.util.concurrent;
  9. import java.util.concurrent.locks.*;
  10.  
  11. /**
  12.  * A cancellable asynchronous computation.  This class provides a base
  13.  * implementation of {@link Future}, with methods to start and cancel
  14.  * a computation, query to see if the computation is complete, and
  15.  * retrieve the result of the computation.  The result can only be
  16.  * retrieved when the computation has completed; the <tt>get</tt>
  17.  * method will block if the computation has not yet completed.  Once
  18.  * the computation has completed, the computation cannot be restarted
  19.  * or cancelled.
  20.  *
  21.  * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
  22.  * {@link java.lang.Runnable} object.  Because <tt>FutureTask</tt>
  23.  * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
  24.  * submitted to an {@link Executor} for execution.
  25.  *
  26.  * <p>In addition to serving as a standalone class, this class provides
  27.  * <tt>protected</tt> functionality that may be useful when creating
  28.  * customized task classes.
  29.  *
  30.  * @since 1.5
  31.  * @author Doug Lea
  32.  * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
  33.  */
  34. public class FutureTask<V> implements RunnableFuture<V> {
  35.     /** Synchronization control for FutureTask */
  36.     private final Sync sync;
  37.  
  38.     /**
  39.      * Creates a <tt>FutureTask</tt> that will upon running, execute the
  40.      * given <tt>Callable</tt>.
  41.      *
  42.      * @param  callable the callable task
  43.      * @throws NullPointerException if callable is null
  44.      */
  45.     public FutureTask(Callable<V> callable) {
  46.         if (callable == null)
  47.             throw new NullPointerException();
  48.         sync = new Sync(callable);
  49.     }
  50.  
  51.     /**
  52.      * Creates a <tt>FutureTask</tt> that will upon running, execute the
  53.      * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
  54.      * given result on successful completion.
  55.      *
  56.      * @param  runnable the runnable task
  57.      * @param result the result to return on successful completion. If
  58.      * you don't need a particular result, consider using
  59.      * constructions of the form:
  60.      * <tt>Future&lt;?&gt; f = new FutureTask&lt;Object&gt;(runnable, null)</tt>
  61.      * @throws NullPointerException if runnable is null
  62.      */
  63.     public FutureTask(Runnable runnable, V result) {
  64.         sync = new Sync(Executors.callable(runnable, result));
  65.     }
  66.  
  67.     public boolean isCancelled() {
  68.         return sync.innerIsCancelled();
  69.     }
  70.  
  71.     public boolean isDone() {
  72.         return sync.innerIsDone();
  73.     }
  74.  
  75.     public boolean cancel(boolean mayInterruptIfRunning) {
  76.         return sync.innerCancel(mayInterruptIfRunning);
  77.     }
  78.  
  79.     /**
  80.      * @throws CancellationException {@inheritDoc}
  81.      */
  82.     public V get() throws InterruptedException, ExecutionException {
  83.         return sync.innerGet();
  84.     }
  85.  
  86.     /**
  87.      * @throws CancellationException {@inheritDoc}
  88.      */
  89.     public V get(long timeout, TimeUnit unit)
  90.         throws InterruptedException, ExecutionException, TimeoutException {
  91.         return sync.innerGet(unit.toNanos(timeout));
  92.     }
  93.  
  94.     /**
  95.      * Protected method invoked when this task transitions to state
  96.      * <tt>isDone</tt> (whether normally or via cancellation). The
  97.      * default implementation does nothing.  Subclasses may override
  98.      * this method to invoke completion callbacks or perform
  99.      * bookkeeping. Note that you can query status inside the
  100.      * implementation of this method to determine whether this task
  101.      * has been cancelled.
  102.      */
  103.     protected void done() { }
  104.  
  105.     /**
  106.      * Sets the result of this Future to the given value unless
  107.      * this future has already been set or has been cancelled.
  108.      * This method is invoked internally by the <tt>run</tt> method
  109.      * upon successful completion of the computation.
  110.      * @param v the value
  111.      */
  112.     protected void set(V v) {
  113.         sync.innerSet(v);
  114.     }
  115.  
  116.     /**
  117.      * Causes this future to report an <tt>ExecutionException</tt>
  118.      * with the given throwable as its cause, unless this Future has
  119.      * already been set or has been cancelled.
  120.      * This method is invoked internally by the <tt>run</tt> method
  121.      * upon failure of the computation.
  122.      * @param t the cause of failure
  123.      */
  124.     protected void setException(Throwable t) {
  125.         sync.innerSetException(t);
  126.     }
  127.  
  128.     // The following (duplicated) doc comment can be removed once
  129.     //
  130.     // 6270645: Javadoc comments should be inherited from most derived
  131.     //          superinterface or superclass
  132.     // is fixed.
  133.     /**
  134.      * Sets this Future to the result of its computation
  135.      * unless it has been cancelled.
  136.      */
  137.     public void run() {
  138.         sync.innerRun();
  139.     }
  140.  
  141.     /**
  142.      * Executes the computation without setting its result, and then
  143.      * resets this Future to initial state, failing to do so if the
  144.      * computation encounters an exception or is cancelled.  This is
  145.      * designed for use with tasks that intrinsically execute more
  146.      * than once.
  147.      * @return true if successfully run and reset
  148.      */
  149.     protected boolean runAndReset() {
  150.         return sync.innerRunAndReset();
  151.     }
  152.  
  153.     /**
  154.      * Synchronization control for FutureTask. Note that this must be
  155.      * a non-static inner class in order to invoke the protected
  156.      * <tt>done</tt> method. For clarity, all inner class support
  157.      * methods are same as outer, prefixed with "inner".
  158.      *
  159.      * Uses AQS sync state to represent run status
  160.      */
  161.     private final class Sync extends AbstractQueuedSynchronizer {
  162.         private static final long serialVersionUID = -7828117401763700385L;
  163.  
  164.         /** State value representing that task is running */
  165.         private static final int RUNNING   = 1;
  166.         /** State value representing that task ran */
  167.         private static final int RAN       = 2;
  168.         /** State value representing that task was cancelled */
  169.         private static final int CANCELLED = 4;
  170.  
  171.         /** The underlying callable */
  172.         private final Callable<V> callable;
  173.         /** The result to return from get() */
  174.         private V result;
  175.         /** The exception to throw from get() */
  176.         private Throwable exception;
  177.  
  178.         /**
  179.          * The thread running task. When nulled after set/cancel, this
  180.          * indicates that the results are accessible.  Must be
  181.          * volatile, to ensure visibility upon completion.
  182.          */
  183.         private volatile Thread runner;
  184.  
  185.         Sync(Callable<V> callable) {
  186.             this.callable = callable;
  187.         }
  188.  
  189.         private boolean ranOrCancelled(int state) {
  190.             return (state & (RAN | CANCELLED)) != 0;
  191.         }
  192.  
  193.         /**
  194.          * Implements AQS base acquire to succeed if ran or cancelled
  195.          */
  196.         protected int tryAcquireShared(int ignore) {
  197.             return innerIsDone()? 1 : -1;
  198.         }
  199.  
  200.         /**
  201.          * Implements AQS base release to always signal after setting
  202.          * final done status by nulling runner thread.
  203.          */
  204.         protected boolean tryReleaseShared(int ignore) {
  205.             runner = null;
  206.             return true;
  207.         }
  208.  
  209.         boolean innerIsCancelled() {
  210.             return getState() == CANCELLED;
  211.         }
  212.  
  213.         boolean innerIsDone() {
  214.             return ranOrCancelled(getState()) && runner == null;
  215.         }
  216.  
  217.         V innerGet() throws InterruptedException, ExecutionException {
  218.             acquireSharedInterruptibly(0);
  219.             if (getState() == CANCELLED)
  220.                 throw new CancellationException();
  221.             if (exception != null)
  222.                 throw new ExecutionException(exception);
  223.             return result;
  224.         }
  225.  
  226.         V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
  227.             if (!tryAcquireSharedNanos(0, nanosTimeout))
  228.                 throw new TimeoutException();
  229.             if (getState() == CANCELLED)
  230.                 throw new CancellationException();
  231.             if (exception != null)
  232.                 throw new ExecutionException(exception);
  233.             return result;
  234.         }
  235.  
  236.         void innerSet(V v) {
  237.         for (;;) {
  238.         int s = getState();
  239.         if (s == RAN)
  240.             return;
  241.                 if (s == CANCELLED) {
  242.             // aggressively release to set runner to null,
  243.             // in case we are racing with a cancel request
  244.             // that will try to interrupt runner
  245.                     releaseShared(0);
  246.                     return;
  247.                 }
  248.         if (compareAndSetState(s, RAN)) {
  249.                     result = v;
  250.                     releaseShared(0);
  251.                     done();
  252.             return;
  253.                 }
  254.             }
  255.         }
  256.  
  257.         void innerSetException(Throwable t) {
  258.         for (;;) {
  259.         int s = getState();
  260.         if (s == RAN)
  261.             return;
  262.                 if (s == CANCELLED) {
  263.             // aggressively release to set runner to null,
  264.             // in case we are racing with a cancel request
  265.             // that will try to interrupt runner
  266.                     releaseShared(0);
  267.                     return;
  268.                 }
  269.         if (compareAndSetState(s, RAN)) {
  270.                     exception = t;
  271.                     result = null;
  272.                     releaseShared(0);
  273.                     done();
  274.             return;
  275.                 }
  276.         }
  277.         }
  278.  
  279.         boolean innerCancel(boolean mayInterruptIfRunning) {
  280.         for (;;) {
  281.         int s = getState();
  282.         if (ranOrCancelled(s))
  283.             return false;
  284.         if (compareAndSetState(s, CANCELLED))
  285.             break;
  286.         }
  287.             if (mayInterruptIfRunning) {
  288.                 Thread r = runner;
  289.                 if (r != null)
  290.                     r.interrupt();
  291.             }
  292.             releaseShared(0);
  293.             done();
  294.             return true;
  295.         }
  296.  
  297.         void innerRun() {
  298.             if (!compareAndSetState(0, RUNNING))
  299.                 return;
  300.             try {
  301.                 runner = Thread.currentThread();
  302.                 if (getState() == RUNNING) // recheck after setting thread
  303.                     innerSet(callable.call());
  304.                 else
  305.                     releaseShared(0); // cancel
  306.             } catch (Throwable ex) {
  307.                 innerSetException(ex);
  308.             }
  309.         }
  310.  
  311.         boolean innerRunAndReset() {
  312.             if (!compareAndSetState(0, RUNNING))
  313.                 return false;
  314.             try {
  315.                 runner = Thread.currentThread();
  316.                 if (getState() == RUNNING)
  317.                     callable.call(); // don't set result
  318.                 runner = null;
  319.                 return compareAndSetState(RUNNING, 0);
  320.             } catch (Throwable ex) {
  321.                 innerSetException(ex);
  322.                 return false;
  323.             }
  324.         }
  325.     }
  326. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement