Callable、Future和FutureTask

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

目录

Callable

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

Future

  • Futurue是一个接口,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。
  • Cancel方法:试图取消任务的执行,如果任务已完成或者已取消或者无法取消,则返回false。如果任务尚未启动,执行此方法后,将不会再运行。如果任务已经启动,则可以选择参数确定是否尝试停止任务
  • isCancelled方法:如果任务正常完成前将其取消,返回true
  • get方法:等待计算完成,然后获取结果
  • isDone方法:如果任务完成,返回true
  1. public interface Future<V> {
  2. boolean cancel(boolean mayInterruptIfRunning);
  3. boolean isCancelled();
  4. boolean isDone();
  5. V get() throws InterruptedException, ExecutionException;
  6. V get(long timeout, TimeUnit unit)
  7. throws InterruptedException, ExecutionException, TimeoutException;
  8. }

FutureTask

  • FutureTask是一个类,实现了RunnableFuture接口,而RunnableFuture接口继承了Runnable和Future接口
  • FutureTask的有两个构造方法,参数是Callable和Runnable
  1. public class FutureTask<V> implements RunnableFuture<V>
  2. {
  3. public FutureTask(Callable<V> callable) {
  4. if (callable == null)
  5. throw new NullPointerException();
  6. this.callable = callable;
  7. this.state = NEW; // ensure visibility of callable
  8. }
  9. public FutureTask(Runnable runnable, V result) {
  10. this.callable = Executors.callable(runnable, result);
  11. this.state = NEW; // ensure visibility of callable
  12. }
  13. }
  14. public interface RunnableFuture<V> extends Runnable, Future<V> {
  15. void run();
  16. }

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用法
  1. public static void main(String[] args)
  2. {
  3. ThreadPoolExecutor tp = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
  4. Future<String> future=tp.submit(new Callable<String>()
  5. {
  6. public String call() throws Exception {
  7. // TODO 自动生成的方法存根
  8. return "jiajun";
  9. }
  10. });
  11. tp.shutdown();
  12. try {
  13. System.out.println(future.get());
  14. System.out.println(future.isCancelled());
  15. System.out.println(future.isDone());
  16. System.out.println(future.cancel(true));
  17. } catch (InterruptedException e) {
  18. // TODO 自动生成的 catch 块
  19. e.printStackTrace();
  20. } catch (ExecutionException e) {
  21. // TODO 自动生成的 catch 块
  22. e.printStackTrace();
  23. }
  24. }
  • FutureTask用法
  1. public static void main(String[] args)
  2. {
  3. ThreadPoolExecutor tp = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
  4. FutureTask <String >future= new FutureTask<String>(new Callable<String>()
  5. {
  6. public String call() throws Exception {
  7. // TODO 自动生成的方法存根
  8. return "jiajun";
  9. }
  10. });
  11. tp.submit(future);
  12. tp.shutdown();
  13. try {
  14. System.out.println(future.get());
  15. System.out.println(future.isCancelled());
  16. System.out.println(future.isDone());
  17. System.out.println(future.cancel(true));
  18. } catch (InterruptedException e) {
  19. // TODO 自动生成的 catch 块
  20. e.printStackTrace();
  21. } catch (ExecutionException e) {
  22. // TODO 自动生成的 catch 块
  23. e.printStackTrace();
  24. }
  25. }
  • 不同的地方,从代码可以看出第一份代码中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/

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

java多线程系列(七)---Callable、Future和FutureTask的更多相关文章

  1. JAVA多线程提高七:Callable与Future的应用

    Callable与Runnable 先说一下java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法: public interface Runnable { publ ...

  2. java多线程系列13 设计模式 Future 模式

    Future 模式 类似于ajax请求  页面异步的进行后台请求 用户无需等待请求的结果 就可以继续浏览或者操作 核心就是:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 ...

  3. Java多线程系列七——ExecutorService

    java.util.concurrent.ExecutorService接口提供了许多线程管理的方法 Method 说明 shutdown 拒绝接收新的任务,待已提交的任务执行后关闭,且宿主线程不阻塞 ...

  4. 【Java多线程系列七】ExecutorService

    java.util.concurrent.ExecutorService接口提供了许多线程管理的方法 Method 说明 shutdown 拒绝接收新的任务,待已提交的任务执行后关闭,且宿主线程不阻塞 ...

  5. (Java多线程系列七)Java内存模型和线程的三大特性

    Java内存模型和线程的三大特性 多线程有三大特性:原子性.可见性.有序性 1.Java内存模型 Java内存模型(Java Memory Model ,JMM),决定一个线程对共享变量的写入时,能对 ...

  6. java多线程系列(八)---CountDownLatch和CyclicBarrie

    CountDownLatch 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线 ...

  7. java多线程系列(九)---ArrayBlockingQueue源码分析

    java多线程系列(九)---ArrayBlockingQueue源码分析 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 j ...

  8. java多线程系列 目录

    Java多线程系列1 线程创建以及状态切换    Java多线程系列2 线程常见方法介绍    Java多线程系列3 synchronized 关键词    Java多线程系列4 线程交互(wait和 ...

  9. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

随机推荐

  1. 【LeetCode】205. Isomorphic Strings

    题目: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the c ...

  2. sql将一列数据拼成一个字符串的方法

    SELECT STUFF(CONVERT(VARCHAR(500), ( SELECT TOP 10 ',' + BG_Country FROM dbo.BS_Budget FOR XML PATH( ...

  3. 序列、视图、索引(面试看这个就GO了)

    oracle内置对象 序列.视图.索引 序列 create sequence aaa start with 1; 使用 视图 创建好之后 然后直接用 就OK了 有了视图可以代替子查询,使得sql简洁 ...

  4. 使用阿里百川HotFix

    前言:首先要弄懂HotFix是干嘛的,不然就别向下看了.这里仅仅根据官方文档的代码书写,亲测可用,不做理论指导. Android Studio集成: 添加maven仓库地址: repositories ...

  5. Linux内核的基本概念

    Linux内核学习,推荐的书籍: <linux设备驱动开发详解第二版>.<Linux内核设计与实现第三版>.<嵌入式Linux应用开发完全手册> 第一篇:讲解Lin ...

  6. Java虚拟机-----------Java内存区域与内存溢出异常

    Java内存区域划分 Java虚拟机运行时的数据区大致可划分为五部分:方法区,堆(两部分组成Java堆内存),虚拟机栈,本地方法栈(Java栈内存),程序计数器. 1.程序计数器 程序计数器占较小的内 ...

  7. 投票系统 & js脚本简单刷票

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. Web自动化之Headless Chrome编码实战

    API 概览 && 编码Tips 文档地址 github Chrome DevTools Protocol 协议本身的仓库 有问题可以在这里提issue github debugger ...

  9. alibaba druid 在springboot start autoconfig 下的bug

    alibaba druid 在springboot start autoconfig下的bug 标签(空格分隔):druid springboot start autoconfig 背景 发现.分析过 ...

  10. 【ALB技术笔记】基于多线程方式的串行通信接口数据接收案例

    基于多线程方式的串行通信接口数据接收案例 广东职业技术技术学院  欧浩源 1.案例背景 在本博客的<[CC2530入门教程-06]CC2530的ADC工作原理与应用>中实现了电压数据采集的 ...