FutureTask原始碼詳解 JDK1 8

2021-10-13 00:06:45 字數 2350 閱讀 9250

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呼叫

需要注意的是方法中的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版本)

8- cancel方法詳解

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 ...