先提交后获取:Future和FutureTesk的异步执行

在上一篇日志中,并行执行下的多线程协作完成查找操作里,我让每一个查找线程实现了Callable接口,从主线程中也看到,使用了Future<Integer>泛型接口来接收线程的返回结果。想了一下,觉得有必要补上一篇日志,总结下自己对Future模式的学习。

使用Runnable还是Callable?

通常我们创建线程都是继承或实现Runnable接口,使用Callable接口和Runnable接口相似,不同之处在于,Runnable接口没有返回值,因为看Runnable接口中,只有一个抽象方法public void run()可以看出,run()方法没有参数传入,返回类型是void,即线程执行完后,不能返回结果。实现Runnable接口的线程如果想要知道执行结果,可能需要通过修改共享变量或者线程间通信的方式告知。而Callable接口是允许有返回值的,先来看看它的源码:

public interface Callable<V> {
    /**
     * 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;
}

可以看到,Callable接口的传入参数类型V,接口里面只有一个方法call(),不过它不是一个抽象方法,而是带返回类型V的方法。也就是说,如果用Callable接口来封装任务,创建线程,则可以获得任务的返回值。

Callable接口使用场景

你可能会想,什么样的场景下需要用到这带返回类型线程?假设一个线程计算任务需要耗费很长时间,它的计算结果我们并不急着需要,在等待该线程计算完成的过程中,我们想充分利用着等待的时间,让CPU去响应其他的线程,等我们需要这个计算结果时,再去拿这个计算任务的返回值。

举个生活中的例子,假如我们想吃云吞做早餐,云吞要放到沸水中煮,在打开电磁炉煮热水,等待水沸腾的过程中,我们可以去把云吞从冰箱里拿出来解冻,此时电磁炉中的水是否沸腾我们不关心,等我们把所有云吞都解冻好了,真正需要放到沸水中煮时,再去打开电磁炉盖,关心此时的水是否已沸腾。

使用Callable接口的线程大概就是这么一个思想,在线程提交执行后,会立刻有返回类型(假设是V),虽然此时线程可能没执行完,之后我们可以通过调用Future.get()方法来获得这个返回值(如果你是把任务返回结果放到Future泛型接口中,你也可以把它放到实现Future接口的类FutureTask类中,同样调用FutureTask.get()方法来获得返回值,下面我会详细说)。

Future接口和FutureTesk类

那么,实现Callable接口的线程,执行结果返回给谁呢?谁来接收实现Callable接口的线程返回值?有两种方式,使用Future泛型接口或使用Future接口的类FutureTesk类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值