美文网首页
同步工具类之FutureTask

同步工具类之FutureTask

作者: evil_ice | 来源:发表于2017-01-10 23:34 被阅读104次
    一,FutureTask概述
    • FutureTask也可以用作闭锁.FutureTask实现了Future语义,表示一种抽象的可生成结果的计算.FutureTask表示的计算是通过Callable来实现的,相当于一种可生成结果的Runnable,并且可以处于以下3种状态:等待运行,正在运行和运行完成.
    • Future.get的行为取决于任务的状态.如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常
    二,Callable, Future, FutureTask的关系
    • Callable
      • Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
      • Callable是对任务的一种更好的抽象
    public interface Callable<V> {
        /**
         * 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<V> {
        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.png
    三,一个小示例
    public class Test {
        public static void main(String[] args){
            FutureAndCallableDemo demo = new FutureAndCallableDemo();
            List<Callable<String>> tasks = new ArrayList<Callable<String>>();
            for(int i=0; i<5; i++){
                tasks.add(new Task());
            }
            
            List<String> results = demo.executeTask(tasks);
            for(String result : results){
                System.out.println(result);
            }
        }
    }
    
    class Task implements Callable<String>{
        @Override
        public String call() throws Exception {
            return Thread.currentThread().getName()+"  "+System.currentTimeMillis();
        }   
    }
    
    class FutureAndCallableDemo{
        ExecutorService executor = Executors.newCachedThreadPool();
        
        public List<String> executeTask(List<Callable<String>> tasks){
            List<String> results = new ArrayList<String>();
            for(Callable<String> task : tasks){
                FutureTask<String> result = new FutureTask<String>(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;
        }
    
    }
    
    

    参考:
    <<java编发编程实战>>

    相关文章

      网友评论

          本文标题:同步工具类之FutureTask

          本文链接:https://www.haomeiwen.com/subject/oiylbttx.html