java中FutureTask的使用

FutureTask简介

FutureTask是java 5引入的一个类,从名字可以看出来FutureTask既是一个Future,又是一个Task。

我们看下FutureTask的定义:

public class FutureTask<V> implements RunnableFuture<V> {
...
}
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}

FutureTask实现了RunnableFuture接口,RunnableFuture接口是Runnable和Future的综合体。

作为一个Future,FutureTask可以执行异步计算,可以查看异步程序是否执行完毕,并且可以开始和取消程序,并取得程序最终的执行结果。

除此之外,FutureTask还提供了一个runAndReset()的方法, 该方法可以运行task并且重置Future的状态。

Callable和Runnable的转换

我们知道Callable是有返回值的,而Runnable是没有返回值的。

Executors提供了很多有用的方法,将Runnable转换为Callable:

    public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}

FutureTask内部包含一个Callable,并且可以接受Callable和Runnable作为构造函数:

    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
}

它的内部就是调用了Executors.callable(runnable, result);方法进行转换的。

以Runnable运行

既然是一个Runnable,那么FutureTask就可以以线程的方式执行,我们来看一个例子:

@Test
public void convertRunnableToCallable() throws ExecutionException, InterruptedException {
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
log.info("inside callable future task ...");
return 0;
}
}); Thread thread= new Thread(futureTask);
thread.start();
log.info(futureTask.get().toString());
}

上面例子是以单个线程来执行的,同样我们也可以将FutureTask提交给线程池来执行:

    @Test
public void workWithExecutorService() throws ExecutionException, InterruptedException {
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
log.info("inside futureTask");
return 1;
}
});
ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(futureTask);
executor.shutdown();
log.info(futureTask.get().toString());
}

本文的例子可参考https://github.com/ddean2009/learn-java-concurrency/tree/master/futureTask

更多教程请参考 flydean的博客

最新文章

  1. SSH实战 &#183; 唯唯乐购项目(上)
  2. Xcode开发小问题集锦
  3. 如何破解Excel文档的编辑密码
  4. Linux下的NFS配置(转)
  5. PTPX中的time_based analysis
  6. [转载] Python的GIL是什么鬼,多线程性能究竟如何
  7. C# 32位md5
  8. 黑马程序员_&lt;&lt;properties,打印流,合并流,分割流&gt;&gt;
  9. JQuery里属性赋值,取值prop()和attr()方法?
  10. 如何显示Mac OS X上的隐藏文件和文件夹
  11. UVa 514 Rails(经典栈)
  12. MT5基础知识
  13. basepath的作用 (转)
  14. Conemu, Msys2 工具整合,提升windows下控制台工作效率
  15. 深入浅出NIO Socket实现机制
  16. typescript中的接口
  17. mac下安装安卓开发环境
  18. locust -基础框架
  19. Navicat连接mysql8.0.1版本出现1251--Client does not support authentication protocol requested by server的解决
  20. ElementUI制作树形表组件

热门文章

  1. Sqli-labs Less-58 报错注入 5次机会
  2. ARM.SchDoc图解
  3. JavaScript中数组的两种排序方法详解(冒泡排序和选择排序)
  4. 部署zookeepe高可用集群
  5. SpringMVC(一):简介和第一个程序
  6. flask-模板使用
  7. 2017蓝桥杯日期问题(C++B组)
  8. npm install报错:chromedriver@2.27.2 install: node install.js
  9. Java入门第一阶段总结
  10. std::string::substr函数