Java FutureTask类使用案例解析

网友投稿 497 2023-06-09

java FutureTask类使用案例解析

FutureTask一个可取消的异步计算,FutureTask 实现了Future的基本方法,提空 start cancel 操作,可以查询计算是否已经完成,并且可以获取计算的结果。结果只可以在计算完成之后获取,get方法会阻塞当计算没有完成的时候,一旦计算已经完成,那么计算就不能再次启动或是取消。

一个FutureTask 可以用来包装一个 Callable 或是一个runnable对象。因为FurtureTask实现了Runnable方法,所以一个 FutureTask可以提交(submit)给一个Excutor执行(excution).

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

我们看下FutureTask的定义:

public class FutureTask implements RunnableFuture {

...

}

public interface RunnableFuture extends Runnable, Future {

/**

* Sets this Future to the result of http://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 Callable callable(Runnable task, T result) {

if (task == null)

throw new NullPointerException();

return new RunnableAdapter(task, result);

}

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

public FutureTask(Callable 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 futureTask = new FutureTask<>(new Callable() {

@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 futureTask = new FutureTask<>(new Callable() {

@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());

}

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:IDEA进程已结束,退出代码
下一篇:Java基于Semaphore构建阻塞对象池
相关文章

 发表评论

暂时没有评论,来抢沙发吧~