zoukankan      html  css  js  c++  java
  • Callable,Future和FutureTask详解

    1.Callable和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;
    }

    看Runnable接口:

    public
    interface Runnable {
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    }

    Callable和Runnable都代表着任务,不同之处在于Callable有返回值,并且能抛出异常,Runnable任务执行结束之后没有返回值。Callable一般和Future一起使用,可以获取任务返回结果。

    2.Future接口

    Future就是对具体的Callable和Runnable任务进行操作,如:取消任务,查询任务是否完成,获取任务完成之后的返回结果(如果有返回值)。看代码:

    public interface Future<V> {
        // 用于取消任务
        boolean cancel(boolean mayInterruptIfRunning);
        // 任务是否被取消成功,如果取消成功,返回true
        boolean isCancelled();
        // 任务是否已经完成,如果完成,返回true
        boolean isDone();
        // 获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回
        V get() throws InterruptedException, ExecutionException;
       // 获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。 
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }

    由接口可知,Future提供了四种功能:

    •   取消任务
    •   判断任务是否取消成功
    •   判断任务是否完成
    •   获取任务执行结果

    通过一个Demo来理解Future的用法:

    public class FutureTest {
        public static class Task implements Callable<String>{
            
            @Override
            public String call() throws Exception {
                System.out.println("开始执行任务。。。");
                return "callable";
            }
            
        }
        
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            ExecutorService es = Executors.newCachedThreadPool();
            List<Future<String>> results = new ArrayList<Future<String>>();
            for(int i = 0;i<100;i++){
                results.add(es.submit(new Task()));
            }
    
            for(Future<String> res : results){
                System.out.println(res.get());
            }
            
        }
        
    }

    3.FutureTask

    public class FutureTask<V> implements RunnableFuture<V>
    public interface RunnableFuture<V> extends Runnable, Future<V> {
        void run();
    }

    从代码可知:FutureTask既可以作为Runnable被线程执行,又具有Future的功能。

    FutureTask的两种使用方式:

    使用方式一:FutureTask+Thread

    public class FutureTest {
        public static class Task implements Callable<String>{
            
            @Override
            public String call() throws Exception {
                System.out.println("开始执行任务。。。");
                return "callable";
            }
            
        }
        
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            //创建FutureTask对象,并传入一个实现了Callable接口的对象作为构造参数
            FutureTask<String> futureTask = new FutureTask<String>(new Task());
            //创建Thread并启动
            Thread thread = new Thread(futureTask);
            thread.start();
        }
        
    }

    使用方式二:FutureTask+ExecutorService

    public class FutureTest {
        public static class Task implements Callable<String>{
            
            @Override
            public String call() throws Exception {
                System.out.println("开始执行任务。。。");
                return "callable";
            }
            
        }
        
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            ExecutorService es = Executors.newCachedThreadPool();
            FutureTask<String> futureTask = new FutureTask<String>(new Task());
            es.submit(futureTask);
        }
        
    }
  • 相关阅读:
    Knockout应用开发指南 第八章:简单应用举例(2)
    微软ASP.NET站点部署指南(7):生产环境部署
    Knockout应用开发指南 第七章:Mapping插件
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(6)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(5)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(3)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(9)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(8)
    Microsoft Visual Studio .NET 2003 引导程序插件下载地址(非官方)
    Vs2010在没有安装SQL Server 2005/2008 Express时如何连接MDF数据文件?
  • 原文地址:https://www.cnblogs.com/51life/p/10142804.html
Copyright © 2011-2022 走看看