jdk1.8修改了futuretask的實現,jkd1.8不再依賴aqs來實現,而是通過乙個volatile變數state以及cas操作來實現。
1- 繼承結構
2- state欄位
volatile修飾的state欄位3- 其他變數
runner和waiters為volatile型別4- 構造器
5- cas工具初始化
6- get()方法的等待佇列
7- run()方法詳解
run()方法一般被executor呼叫8- cancel方法詳解需要注意的是方法中的catch子句,如果caller執行緒呼叫cancel(true)方法來中斷runner執行緒任務的執行,除非在callable的call()方法實現上設計成響應執行緒中斷,否則是不會中斷callable.call()方法的執行的。
喚醒get()方法阻塞的執行緒
重點看一下handlepossiblecancellationinterrupt方法:這個方法是自旋等待state變為interrupted(對應cancel方法的結束),即等待中斷的結束。
作者本來想在方法的尾部呼叫thread.interrupted()方法來重置runner執行緒的中斷狀態的,但是考慮到程式設計師設計程式時可能使用中斷作為task和caller之間的通訊,如果貿然的清除中斷標誌,可能會給程式設計者帶來不便,所以既然不能保證一定是cancel(true)導致的中斷,那麼就不清除了,最終將最後一行注釋了。所以最終的結果還是讓runner保持中斷狀態。(基於jdk1.8.0_65版本)
9- get方法詳解
new 狀態的 futuretask 的 get 方法將會被阻塞,直到被喚醒從迴圈中返回。10- 總結
jdk的原始碼文件中作者新增了如下修改注釋
講解了自己在jdk1.8中重新futuretask的意圖是想避免在執行取消的迴圈中runner還一直保持中斷狀態,所以想在取消的迴圈中重置runner的中斷狀態,但是又考慮到如下事實:程式設計師設計程式時可能使用中斷作為task和caller之間的通訊。所以貿然的清除中斷標誌,可能會給程式設計者帶來不便,所以既然不能保證一定是cancel(true)導致的中斷,那麼就不清除了,最終將最後一行注釋了。所以最終的結果還是讓runner保持中斷狀態。(基於jdk1.8.0_65版本)當cancel(true)去以中斷的方式中斷任務的執行時,除非在callable的call()方法實現上設計成響應執行緒中斷,否則是不會中斷callable.call()方法的執行的,雖然不會中斷任務的執行,但是不會設定callable的執行結果,在get()方法返回時丟擲cancellationexception異常。
FutureTask 原始碼閱讀
public void run catch throwable ex if ran set result finally get操作的核心方法 private intawaitdone boolean timed,long nanos throws interruptedexception int ...
FutureTask原始碼分析
futuretask實現了runnablefuture,runnablefuture繼承了runnable和future介面。future介面和實現future介面的futuretask類,代表非同步計算的結果。所以futuretask既能當做乙個runnable直接被thread執行,也能作為fu...
FutureTask原始碼分析
private volatile int state 任務狀態 private static final int new 0 private static final int completing 1 private static final int normal 2 private static ...