Callable, Future和FutureTask简述
Posted _houzhi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Callable, Future和FutureTask简述相关的知识,希望对你有一定的参考价值。
JDK1.5后新增了一些接口用于并发编程的接口,Callable,Future。以及1.6添加了FutureTask。之前看到了他们的使用,JDK1.8还添加了CompletableFuture,一直想了解一下这些东西。这里记录下对Callable, Future和FutureTask的理解。
相关接口
FutureTask实现了RunnableFuture接口,而RunnableFuture继承了Runnable,Future接口。FutureTask又有一个Callable参数的构造函数,下面分别介绍这些接口。
Runnable
这个是在Java一开始就出现了的接口,只有一个接口方法run,表示可以被运行的类。可以放到线程池,Thread中运行。跟Thread是两种不同的实现方式。
Future
这是在JDK1.5新增的接口,展示异步执行的结果(结果,将来的,Future)。他有以下几个方法:
- cancel: 尝试去取消这个任务,如果该任务已经完成,或者已经取消,或者其他什么原因将不能取消。
- get: 可以通过get方法获取异步线程的结果,如果没有执行完成则阻塞当前线程,等待异步线程执行完获取结果。
- isDone: 判断该任务是否已经完成。如果是被取消,中断等,该方法也会返回true。
- isCancelled: 判断该任务是否已经取消。
Runnable和Thread都有一个问题,就是不能够直接获取异步线程运行的结果,而Future可以做到。
RunnableFuture
实现了Runnable接口和Future接口。
Callable
一个可以返回结果的接口。只有一个方法call。
使用范例
使用Callable放到线程池中运行。
public class TestFuture
public static void main(String[] args) throws InterruptedException, ExecutionException
ExecutorService executor = Executors.newCachedThreadPool();
Task task = new Task();
Future<Integer> future = executor.submit(task);
// do something
System.out.println("可以先做一些事情,再去获取运行结果");
if(!future.isDone())
// you also can do something.
System.out.println("运行结果: "+future.get()); // 可能会阻塞等待结果
static class Task implements Callable<Integer>
@Override
public Integer call() throws Exception
System.out.println("异步任务开始运行");
TimeUnit.SECONDS.sleep(3);
int sum = 0 ;
for(int i = 0 ; i != 200; ++i)
sum+=i;
System.out.println("异步任务完成运行");
return sum;
//运行结果
/*
可以先做一些事情,再去获取运行结果
异步任务开始运行
异步任务完成运行
运行结果: 19900
*/
可以自己实现Callable接口,Executor执行完成后会返回一个Future对象。在获取运行结果前,可以先做一些其他的事情。
使用FutureTask
public class TestFutureTask
public static void main(String[] args) throws InterruptedException, ExecutionException
ExecutorService executor = Executors.newCachedThreadPool();
FutureTask<Integer> futureTask = new FutureTask<Integer>(new Task());
executor.submit(futureTask); //调用的submit(Runnable runnable) 方法
// do something
System.out.println("可以先做一些事情,再去获取运行结果");
if(!futureTask.isDone())
// you also can do something.
System.out.println("运行结果: "+futureTask.get()); // 可能会阻塞等待结果
static class Task implements Callable<Integer>
@Override
public Integer call() throws Exception
System.out.println("异步任务开始运行");
TimeUnit.SECONDS.sleep(3);
int sum = 0 ;
for(int i = 0 ; i != 200; ++i)
sum+=i;
System.out.println("异步任务完成运行");
return sum;
跟前面直接使用Callable结果是一样的,只是使用方式有点不一样。这里不需要从submit中获得Future对象,直接就是传入的那个参数futureTask,在有些使用使用起来会更加方便。
总结
我觉得Future接口提供了一种异步操作新的思路,Runnable和Thread都是直接执行完就没有了,并没有获得执行结果的接口,但是Future可以获得执行结果。Future就是用来展示执行结果。当然Future这一系列接口的使用远远不止这些,Future的get方法还可以设置超时时间。
以上是关于Callable, Future和FutureTask简述的主要内容,如果未能解决你的问题,请参考以下文章