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

      

 

 

 

   

 

 



  

 

 



 

 

 

 

    

 

   


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM