1 为什么需要Callable和Future

Runnable没有返回值,也不抛异常,这样主线程不能知道子线程的执行结果。

为了解决这个问题就有了Callable和Future。Callable提供的call方法返回一个结果,然后把这个结果交给Future,主线程通过Future就能够获取子线程执行的结果了。

Callable给子线程提供入参,Future提供子线程的返回值。FutureTask合二为一,它把Callable作为成员保存起来,而它本身就是一个Future。

2 什么是Future

Future被用来表示一个异步计算的未来结果。

Future提供了5个接口来查询异步任务的计算结果:

isDone:是否执行完了。

两个get,一个阻塞,一个计时阻塞。

cancel,取消任务的执行。

isCanceled,查询任务是否取消了执行。

3 Future有什么用

3.1 异步调用和并发

耗时的计算适用于异步和Future。

3.2 Future异步计算的使用举例

计算密集的任务;

处理大的数据结构;

远程方法调用:下载文件、web服务等

4 Future是如何实现的

Future能实现本质上是因为java的对象都是放在堆上的。FutureTask是在主线程中创建的对象,将之交给其它线程或者线程池去执行,线程执行完了之后,有一个返回值,将该返回值放在FutureTask的成员outcome上。然后,FutureTask再提供get函数来给主线程获取这个执行的结果。

4.1 FutureTask get实现的原理

第一,维护一个状态机,用户调用get之后,根据不同的执行状态,返回不同的值。

第二,如果任务还没有执行完,就把该线程放入等待队列,并且调用LockSupport.park()函数让阻塞该线程,这样get就阻塞了。

第三,在任务执行完了之后,会把这些等待队列中的线程踢出,并且调用LockSupport.unpark()函数解除阻塞,线程被唤醒。

5 Runnable和Callable比较

5.1 相同点

Runnable和Callable都提供线程的执行体。

5.2 Runable不提供返回值,也不抛异常。Callable提供返回值,可能会抛一个异常

比如FutureTask实现了Callable接口,call方法执行了之后将结果放在FutureTask的outcome成员中。

调用get的时候,如果执行体正常执行则返回该outcome,如果不正常执行就返回Exception。

6 Callable的使用场景

6.1 和Thread一起使用

需要一个中间人FutureTask,该类实现了Runnable和Future接口。因为实现了Runnable接口,因此可以作为参数传给Thread,创建一个新的thread。

FutureTask也可以作为参数传给线程池。

7 总结一下

Callable和Future一起使用来获取异步执行的结果。Callable作为入参,提供线程的执行体和该异步计算的返回值。Future作为异步计算的返回结果。

8 grpc中对Future的使用,grpc是如何通过Future来实现对异步调用结果的获取的?

异步调用时,服务器端调用执行完了,执行的结果是如何交给客户端的?

io是netty实现的,服务器端的调用执行之后,通过通道告知客户端,然后客户端就调用相应的listener。netty的服务器端和客户端都是有多路复用器的。用于监听各个IO事件。

10  参考资料

10.1 https://www.baeldung.com/java-future

10.2 https://www.geeksforgeeks.org/callable-future-java/

10.3 https://blog.csdn.net/codershamo/article/details/51901057

最新文章

  1. IIS7+windows 64位配置注意事项
  2. consul 安装
  3. hdu 5726(二分)
  4. Java:网络编程之IP、URL
  5. Android RecyclerView使用详解(一)
  6. 安装SQL SERVER2005时,需要win7下安装IIS,记录下
  7. PC机安装android apk | adb install -r
  8. Android使用OKHTTP解析JSON数据
  9. Python编程核心内容之一——Function(函数)
  10. vbs中对excel的常用操作
  11. [bzoj1692][队列变换]
  12. python nmap
  13. 试试SQLServer 2014的内存优化表
  14. Fiddler 简介
  15. Java中输出正则表达式匹配到的内容
  16. Entity Framework学习初级篇3--LINQ TO Entities
  17. Html5——canvas标签使用
  18. crontab使用环境变量
  19. Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
  20. mxnet(gluon) 实现DQN简单小例子

热门文章

  1. android Broadcast 总结
  2. ambari journalnode异常Can't scan a pre-transactional edit log
  3. Java 7 新功能: 省略finally, 保证资源正常关闭
  4. etcd的原理分析
  5. 修改MySQL数据库存储位置datadir
  6. 2017.5.1 使用fat jar插件来打包有引用外部jar包的项目
  7. 倍福TwinCAT(贝福Beckhoff)基础教程 松下官方软件开启报错伺服未就绪怎么办
  8. nonlocal(非局部变量)---python 3.x 新增关健词
  9. Excel如何取消显示分页虚线
  10. .aspx 页面引用命名空间