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