Callable,Future,FutureTask

1.概念定義
2.實現例子
3.總結
 
1.概念定義
 
1.Callable
Callable是一個接口,效果相似Runnable接口。實現該接口,而後,耗時操做在call()方法中執行。與Runnable接口不一樣的是,call方法須要返回執行的結果。
public interface Callable<V>{
  V call() throws Exception;
}

public interface Runnable{
  void run();
}
View Code
2.Future
A Future represents the result of an asynchronous(異步的) computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future<?> and return null as a result of the underlying task.
Future是一個接口,實現這個接口的對象具有的特徵,能夠取消任務,獲取任務的結果,判斷任務的執行狀態。Future就是對具體的Callable任務或者Runnable任務執行取消,獲取結果,獲取當前狀態。
public interface Future<V> {

   boolean cancel(boolean mayInterruptIfRunning);
   boolean isCancelled();
   boolean isDone();
   V get() throws InterruptedException, ExecutionException;
   V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
View Code
3.FutureTask
A cancellable asynchronous computation. This class provides a base implementation of Future, with methods to start and cancel a computation, query to see if the computation is complete, and retrieve the result of the computation. The result can only be retrieved when the computation has completed; the get methods will block if the computation has not yet completed. Once the computation has completed, the computation cannot be restarted or cancelled (unless the computation is invoked using  runAndReset()).
A FutureTask can be used to wrap a  Callable or  Runnable object. Because FutureTask implements Runnable, a FutureTask can be submitted to an  Executor for execution.
In addition to serving as a standalone class, this class provides protected functionality that may be useful when creating customized task classes.
FutureTask實現了Future接口,實現了Runnable接口。那麼,它就是一個Runnable對象,Future對象。它的run方法就是執行耗時的操做。
應用:
//建立FutureTask對象,傳入Callable對象;Callable對象,耗時操做是放在call方法裏面的
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
       
       public static void main(String[] args) {
             
             
             Callable<String> worker = new Callable<String>() {
                    
                    @Override
                    public String call() throws Exception {
                           // TODO Auto-generated method stub
                           System.out.println("do computation");
                           return "computation result";
                    }
             } ;
             
             
             FutureTask<String> future = new FutureTask<String>(worker) {
                    @Override
                    protected void  done() {
                           
                       System.out.println("Done task");     
                    }
             };
             
             new Thread(future) {
                    
                    @Override
                    public void run() {
                           future.run();
                    }
                    
             }.start();
             
             try {
                    System.out.println("computation:"+future.get());
             } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }
       }
}
View Code

調用FutureTask的run方法就觸發執行,能夠查看FutureTask的源碼獲得解釋:調用run,會致使調用sync.innerRun();而innerRun會調用傳入的Callable對象的call方法:html

public class FutureTask<V> implements RunnableFuture<V> {


    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        sync = new Sync(callable);
    }

.....
    // The following (duplicated) doc comment can be removed once
    //
    // 6270645: Javadoc comments should be inherited from most derived
    //          superinterface or superclass
    // is fixed.
    /**
     * Sets this Future to the result of its computation
     * unless it has been cancelled.
     */
    public void run() {
        sync.innerRun();
    }

    /**
     * Synchronization control for FutureTask. Note that this must be
     * a non-static inner class in order to invoke the protected
     * <tt>done</tt> method. For clarity, all inner class support
     * methods are same as outer, prefixed with "inner".
     *
     * Uses AQS sync state to represent run status
     */
    private final class Sync extends AbstractQueuedSynchronizer {
    
           void innerRun() {
            if (!compareAndSetState(READY, RUNNING))
                return;

            runner = Thread.currentThread();
            if (getState() == RUNNING) { // recheck after setting thread
                V result;
                try {
                    result = callable.call();
                } catch (Throwable ex) {
                    setException(ex);
                    return;
                }
                set(result);
            } else {
                releaseShared(0); // cancel
            }
        }

    }

}
View Code

 

2.實現例子java

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
       
       public static void main(String[] args) {
             
             
             Callable<String> worker = new Callable<String>() {
                    
                    @Override
                    public String call() throws Exception {
                           // TODO Auto-generated method stub
                           System.out.println("do computation");
                           return "computation result";
                    }
             } ;
             
             
             FutureTask<String> future = new FutureTask<String>(worker) {
                    @Override
                    protected void  done() {
                           
                       System.out.println("Done task");     
                    }
             };
             
             new Thread(future) {
                    
                    @Override
                    public void run() {
                           future.run();
                    }
                    
             }.start();
             
             try {
                    System.out.println("computation:"+future.get());
             } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
             }
       }
}
View Code

 

3.總結api

1.FutureTask就是一個Runnable對象,也是一個Future對象。
2.使用FutureTask要使用Callable對象
3.最終的耗時操做,計算是在Callable對象的call方法中執行
4.使用FutureTask是爲了得到Future接口定義的特性,能夠得到一個任務的執行狀態,執行結果,能夠取消任務的執行。這都是Runnable對象不具有的特性,Thread對象也不具有這些特性。
相關文章
相關標籤/搜索