FutureTask类的get方法如何实现线程同步等待
接上篇JDK中线程中实现同步等待闭环的一种方式 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com),为什么使用了FutureTask中的get方法就可以实现线程的同步等待?这就将重点讲述下FutureTask这个类了,实际上Future接口和实现Future接口的FutureTask类,代表异步计算的结果。其UML类继承图,如下:
从上图看FutureTask除了实现Future接口外,还实现了Runnable接口。因此,FutureTask可以交给Executor执行,也可以由调用线程直接执行(FutureTask.run())。根据FutureTask.run()方法被执行的时机,FutureTask可以处于下面3种状态(线程状态转换参考线程基本方法及其对线程状态的影响 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)):
1)未启动。FutureTask.run()方法还没有被执行之前,FutureTask处于未启动状态。当创建一个FutureTask,且没有执行FutureTask.run()方法之前,这个FutureTask处于未启动状态。
2)已启动。FutureTask.run()方法被执行的过程中,FutureTask处于已启动状态。
3)已完成。FutureTask.run()方法执行完后正常结束,或被取消(FutureTask.cancel(…)),或执行FutureTask.run()方法时抛出异常而异常结束,FutureTask处于已完成状。
当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞;当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常——非常类似于闭锁的语义。
看看get()方法的实现:
通过源码可以看到:get()方法使用AQS类型的同步状态来持有任务的状态——运行、完成或者取消(state变量),同时利用state变量也维护了一些额外的状态变量来持有计算的结果或者抛出异常。与利用AQS类实现同步器的类是不是似曾相识(#^.^#),所以FutureTask虽然代表异步执行的结果,但是可以通过get方法阻塞当前正在运行的线程实现同步等待异步结果。
其还维护一个WaitNode q 指向正在运行计算任务的线程(当前正处于运行状态),这样任务被取消就可以终端该线程:
get()方法的执行示意图如下图上半部分:
最新文章
- 纪念我曾经的 JAVA 姿势--转
- 页面之间传值方式的总结,五种方式,通知,block,代理,单例,NSUERDEFALUT,
- iOS CADisplayLink 定时器的使用
- HDU 2577 How to Type(dp题)
- [百度空间] [原]DLL导出实例化的模板类
- PHP面试题三
- Mysql优化之创建高性能索引(二)
- Javascript 设计模式笔记
- spark 机器学习基础 数据类型
- [已解决]Cannot find one or more components.Please reinstall the application
- How to Configure Email Notification in Jenkins
- [C++ Primer Plus] 第6章、分支语句和逻辑运算符(二)课后习题
- Memcache_分布式缓存
- JAVA 程序的基本语法
- JQuery请求数据的方式
- oracle 快速复制表结构、表数据
- 精巧好用的DelayQueue 转
- JBoss AS 7之基本配置和部署(The Return Of The King)
- Excel 2010 对号叉号怎么打出来
- react项目 路径优化