• java多线程系列(七)---Callable、Future和FutureTask


    Callable、Future和FutureTask

    前言:如有不正确的地方,还望指正。

    目录

    Callable

    • Callable接口和Runnable接口的作用类似
    • 不同的是Callble接口call方法有返回值,返回的是传进来的V类型,而Runnable接口run方法无返回值
    public interface Runnable {
    
        public abstract void run();
    }
    public interface Callable<V> {
     
        V call() throws Exception;
    }
    

    Future

    • Futurue是一个接口,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。
    • Cancel方法:试图取消任务的执行,如果任务已完成或者已取消或者无法取消,则返回false。如果任务尚未启动,执行此方法后,将不会再运行。如果任务已经启动,则可以选择参数确定是否尝试停止任务
    • isCancelled方法:如果任务正常完成前将其取消,返回true
    • get方法:等待计算完成,然后获取结果
    • isDone方法:如果任务完成,返回true
    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

    • FutureTask是一个类,实现了RunnableFuture接口,而RunnableFuture接口继承了Runnable和Future接口
    • FutureTask的有两个构造方法,参数是Callable和Runnable
    public class FutureTask<V> implements RunnableFuture<V>
    {
         public FutureTask(Callable<V> callable) {
            if (callable == null)
                throw new NullPointerException();
            this.callable = callable;
            this.state = NEW;       // ensure visibility of callable
        }
    
       
        public FutureTask(Runnable runnable, V result) {
            this.callable = Executors.callable(runnable, result);
            this.state = NEW;       // ensure visibility of callable
        }
    }
    public interface RunnableFuture<V> extends Runnable, Future<V> {
        
        void run();
    }
    

    AbstractExecutorService的submit方法

    • AbstractExecutorService是一个抽象类,也是ThreadPoolExecutor的父类

    • public class ThreadPoolExecutor extends AbstractExecutorService

    • public Future<?> submit(Runnable task)

    • public <T> Future <T> submit< Runnable task, T result>

    • public <T> Future<T> submit < Callable <T> task >

    • 对比ThreadPoolThread的execute方法,execute无返回值,而三个submit方法返回的都是Future,可以获取任务执行结果,还可以取消任务

    使用

    • Future用法
    public static void main(String[] args)
    	{
    	    
    	    ThreadPoolExecutor tp = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
    	    Future<String> future=tp.submit(new Callable<String>()
    	    {
    
    			public String call() throws Exception {
    				// TODO 自动生成的方法存根
    				
    				return "jiajun";
    			}
    	    	
    	    });
    	    
    	    tp.shutdown();
    	    try {
    			System.out.println(future.get());
    			System.out.println(future.isCancelled());
    			System.out.println(future.isDone());
    			System.out.println(future.cancel(true));
    		} catch (InterruptedException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    	}
    
    • FutureTask用法
    public static void main(String[] args)
    	{
    	    
    	    ThreadPoolExecutor tp = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
    	    
    	    FutureTask <String >future= new FutureTask<String>(new Callable<String>()
    	    {
    
    			public String call() throws Exception {
    				// TODO 自动生成的方法存根
    				
    				return "jiajun";
    			}
    	    	
    	    });
    	    
    	    tp.submit(future);
    	    
    	    tp.shutdown();
    	    try {
    			System.out.println(future.get());
    			System.out.println(future.isCancelled());
    			System.out.println(future.isDone());
    			System.out.println(future.cancel(true));
    		} catch (InterruptedException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			// TODO 自动生成的 catch 块
    			e.printStackTrace();
    		}
    	}
    
    • 不同的地方,从代码可以看出第一份代码中future作为submit方法的返回值,而第二份代码,futureTask作为submit方法的参数。

    总结

    • Callable和Runable都是接口,二者作用类似,不同的是Callable有返回值,而Runnable无返回值
    • Callable一般和ExecutorService一起使用,其返回的值是submit方法返回的Future得到的
    • Future可以查看任务执行情况,可以取消任务
    • 有时候并不需要返回值,但是由于需要可取消任务,所以使用submit方法而不使用execute方法
    • FutureTask是一个类,实现了RunnableFuture接口(继承了Runnable和Future接口),FutureTask可以做为submit方法的参数,并通过FutureTask可以查看任务执行状态

    我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

    作者:jiajun 出处: http://www.cnblogs.com/-new/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

  • 相关阅读:
    Cefsharp支持MP4和MP3的CEF库cef.redist.x86.3.2623,对应Cefsharp49
    解读设计模式
    模拟支付宝、淘宝登录2
    模拟支付宝、淘宝登录1
    上一篇随笔是2011-11-21 17:23,唏嘘啊。。。
    像素格式
    YUV格式详解
    认识RGB和YUV
    WPF性能优化经验总结
    【日期正则表达式】
  • 原文地址:https://www.cnblogs.com/-new/p/7364546.html
Copyright © 2020-2023  润新知