接上篇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()方法的执行示意图如下图上半部分:

      

   

  



    

  

最新文章

  1. 纪念我曾经的 JAVA 姿势--转
  2. 页面之间传值方式的总结,五种方式,通知,block,代理,单例,NSUERDEFALUT,
  3. iOS CADisplayLink 定时器的使用
  4. HDU 2577 How to Type(dp题)
  5. [百度空间] [原]DLL导出实例化的模板类
  6. PHP面试题三
  7. Mysql优化之创建高性能索引(二)
  8. Javascript 设计模式笔记
  9. spark 机器学习基础 数据类型
  10. [已解决]Cannot find one or more components.Please reinstall the application
  11. How to Configure Email Notification in Jenkins
  12. [C++ Primer Plus] 第6章、分支语句和逻辑运算符(二)课后习题
  13. Memcache_分布式缓存
  14. JAVA 程序的基本语法
  15. JQuery请求数据的方式
  16. oracle 快速复制表结构、表数据
  17. 精巧好用的DelayQueue 转
  18. JBoss AS 7之基本配置和部署(The Return Of The King)
  19. Excel 2010 对号叉号怎么打出来
  20. react项目 路径优化

热门文章

  1. 利用Word2010制作流程图
  2. 小程序canvas绘制纯色圆角区域 setdata数组某一项
  3. 新手学习Java,如何快速从入门到精通!
  4. 【C++】类-基础知识
  5. 【算法】nSum问题
  6. 网络流 HLPP 板子
  7. Go 转义字符及风格
  8. java多态转型II
  9. IoC容器-Bean管理XML方式(引入外部属性文件)
  10. Android性能优化之Android 10+ dex2oat实践