在这里首先介绍下Callable和Future,我们知道通常创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口,但是这两种方式创建的线程不返回结果,而Callable是和Runnable类似的接口定义,但是通过实现Callable接口创建的线程可以有返回值,返回值类型可以任意定义。

Callable接口

public interface Callable {

/**

* 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;

}

可以看到,这是一个泛型接口,call()函数返回的类型就是传递进来的V类型。

那么怎么使用Callable呢?一般情况下是配合ExecutorService来使用的,在ExecutorService接口中声明了若干个submit方法的重载版本:

Future submit(Callable task);

Future submit(Runnable task, T result);

Future> submit(Runnable task);

第一个submit方法里面的参数类型就是Callable。Callable一般是和ExecutorService配合来使用的,通过ExecutorService的实例submit得到Future对象。

Future

Future接口如下:

public interface Future {

boolean cancel(boolean mayInterruptIfRunning);// 试图取消对此任务的执行

boolean isCancelled(); // 如果在任务正常完成前将其取消,则返回true

boolean isDone(); // 如果任务已完成(不管是正常还是异常),则返回true

V get() throws InterruptedException, ExecutionException; // 方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;

// 用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null;

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

}

Future用于表示异步计算的结果。它的实现类是FutureTask。

如果不想分支线程阻塞主线程,又想取得分支线程的执行结果,就用FutureTask

FutureTask实现了RunnableFuture接口,这个接口的定义如下:

public interface RunnableFuture extends Runnable, Future

{

void run();

}

可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

使用示例

package demo.future;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.*;

/**

* 试验 Java 的 Future 用法

*/

public class FutureTest {

public static class Task implements Callable {

@Override

public String call() throws Exception {

String tid = String.valueOf(Thread.currentThread().getId());

System.out.printf("Thread#%s : in call\n", tid);

return tid;

}

}

public static void main(String[] args) throws InterruptedException, ExecutionException {

List> results = new ArrayList>();

ExecutorService es = Executors.newCachedThreadPool();

for(int i=0; i<100;i++)

results.add(es.submit(new Task()));

for(Future res : results)

System.out.println(res.get());

}

}

终结任务

持有Future对象,可以调用cancel(),并因此可以使用它来中断某个特定任务,如果将ture传递给cancel(),那么它就会拥有该线程上调用interrupt()以停止这个线程的权限。因此,cancel()是一种中断由Executor启动的单个线程的方式。

cancel()一般是搭配get()方法来使用的。比方说,有一种设计模式是设定特定的时间,然后去执行一个作业的线程,如果该作业能够在设定的时间内执行完毕,则直接返回结果,如果不能执行完毕,则中断作业的执行,继续执行下一个作业,在这种模式下,使用Callable和Future来实现是一个非常好的解决方案。

java终结方法_Java终结任务:Callable和Future相关推荐

  1. java线程方法_Java线程的三种方式

    创建线程有三种方式: 1.继承Thread类 2.实现Runnable接口 3.使用Callable和Future创建线程 三种方式详解如下: ---------------------------- ...

  2. java clone方法_Java Calendar clone()方法与示例

    java clone方法 日历类clone()方法 (Calendar Class clone() method) clone() method is available in java.util p ...

  3. java void方法_Java对象类的最终void wait(long ms)方法,包含示例

    java void方法 对象类最终无效等待(长毫秒) (Object Class final void wait(long ms)) This method is available in java. ...

  4. java tostring方法_Java虚拟机如执行方法调用的(二)?

    虚方法调用 Java里所有非私有实例方法调用都会被编译成invokevirtual指令. 接口方法调用都会被编译成invokeinterface指令.这两种指令都属于Java虚方法的调用. 在大多数情 ...

  5. java peek方法_Java ArrayDeque peek()方法与示例

    java peek方法 ArrayDeque类peek()方法 (ArrayDeque Class peek() method) peek() Method is available in java. ...

  6. java double方法_Java Double类compare()方法与示例

    java double方法 双类compare()方法 (Double class compare() method) compare() method is available in java.la ...

  7. java 析构方法_java析构方法详解

    之前给大家介绍了一下java构造方法,那么下面要给大家讲到的就是java析构方法,下面一起通过文章来了解一下吧. 析构方法和构造方法不同,真好是相反的,在对象脱离其作用域的时候,系统自动执行析构方法. ...

  8. java 获取方法_Java 反射理解(三)-- Java获取方法信息

    Java 反射理解(三)-- Java获取方法信息 基本的数据类型.void关键字,都存在类类型. 举例如下: public class ClassDemo2 { public static void ...

  9. [转载] java clone方法_Java Calendar clone()方法与示例

    参考链接: Java中的Clone()方法 java clone方法 日历类clone()方法 (Calendar Class clone() method) clone() method is av ...

最新文章

  1. Linux shell脚本判断服务器网络是否可以上网
  2. Discuz! X3.2新增管理员无法登录后台的解决办法
  3. SqlServer性能监控和优化总结
  4. eclipse导入项目Archive for required library cannot be read or is not a valid ZIP file
  5. 服务器搬迁方案_数据中心机房改造搬迁IDC机房工程建设
  6. 【C++grammar】string类和array类
  7. 二分查找(递归和非递归实现)
  8. java runnable 启动_Java多线程:线程的创建与启动
  9. Eclipse优化设置技巧
  10. Scintilla教程(2): 文本检索与修改
  11. Oracle 锁表问题查询处理
  12. 经典面试题 Ipv4 和 Ipv6 是什么
  13. 前端开发最基本的3个语言
  14. Vue的计算属性computed和监听属性watch
  15. protoc protoc-gen-go安装
  16. useLocalStorage
  17. Java Bean 转 Map 的巨坑,注意了!!!
  18. java计算算术表达式
  19. Jquery.form自动提交表单上传图片
  20. 超融合架构和传统架构有什么区别?

热门文章

  1. 桔子浏览器电脑版看不了视频怎么办 视频无法播放怎么解决
  2. cordova报错“No installed build tools found. Install the Android build tools version - ”
  3. java生日正则表达式_Java编程基础15——正则表达式常用工具类
  4. mybatis里mapper.xml中SQL语句if语句嵌套if语句
  5. iperf测试带宽linux,iperf3-网络带宽性能测试工具
  6. pat乙级 1014 java_pat乙级1014 福尔摩斯的约会
  7. linux时间跳变影响,MONGO 集群 修改linux主机时间后的影响
  8. 计算机网络客户服务器应用,计算机网络工程教学资料-项目九 Internet服务器应用.pptx...
  9. python enumeration_如何在python中将int转换为Enum?
  10. 输入引脚时钟约束_最强干货分享 | 时钟树例外(exclude pin、stop pin、non_stop pin、float pin)...