• 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);
        }
        
    }
  • 相关阅读:
    python百度ai的银行卡识别代码
    python百度ai的身份证识别代码
    Linux下安装jupyter
    HADOOP 与 jupyterlab 链接
    csv文件数据导出到mongo数据库
    Contos7 常用命令
    centos 安装Python3 及对应的pip
    PHP 连接数据库
    java 注解学习记录
    java简单实现搜索指定后缀文件
  • 原文地址:https://www.cnblogs.com/51life/p/10142804.html
Copyright © 2020-2023  润新知