同步工具类之FutureTask

一,FutureTask概述
  • FutureTask也可以用作闭锁.FutureTask实现了Future语义,表示一种抽象的可生成结果的计算.FutureTask表示的计算是通过Callable来实现的,相当于一种可生成结果的Runnable,并且可以处于以下3种状态:等待运行,正在运行和运行完成.
  • Future.get的行为取决于任务的状态.如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常
二,Callable, Future, FutureTask的关系
  • Callable
    • Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
    • Callable是对任务的一种更好的抽象
public interface Callable {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

  • Future
    • Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future 形式类型、并返回 null 作为底层任务的结果。
    • Future表示一个任务的生命周期,并提供了响应的方法来判断是否已经完成或取消,以及获取任务的结果或者取消任务等.
public interface Future {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

  • FutureTask
    • 可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。
    • 可使用 FutureTask 包装 Callable 或 Runnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。
    • FutureTask的继承关系
同步工具类之FutureTask_第1张图片
FutureTask.png
三,一个小示例
public class Test {
    public static void main(String[] args){
        FutureAndCallableDemo demo = new FutureAndCallableDemo();
        List> tasks = new ArrayList>();
        for(int i=0; i<5; i++){
            tasks.add(new Task());
        }
        
        List results = demo.executeTask(tasks);
        for(String result : results){
            System.out.println(result);
        }
    }
}

class Task implements Callable{
    @Override
    public String call() throws Exception {
        return Thread.currentThread().getName()+"  "+System.currentTimeMillis();
    }   
}

class FutureAndCallableDemo{
    ExecutorService executor = Executors.newCachedThreadPool();
    
    public List executeTask(List> tasks){
        List results = new ArrayList();
        for(Callable task : tasks){
            FutureTask result = new FutureTask(task);
            Thread thread = new Thread(result);
            thread.start();
            try {
                results.add(result.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        return results;
    }

}

参考:
<>

你可能感兴趣的:(同步工具类之FutureTask)