JUC FutureTask個人理解

2021-09-16 12:40:25 字數 2023 閱讀 3867

futuretask是乙個可取消的非同步計算框架。其中內部用的是state來記錄任務的執行狀態。

如上所示futruetask內部封裝了以上的object。所有通過呼叫futuretask執行的任務都會在齊內部包裝成乙個callable來執行。

以上貼出的兩個futuretask的建構函式,要麼直接構造乙個實現了callable介面的物件,要麼傳入乙個實現runnable介面的物件,在其內部將runnable轉換為callable。

接下來看看futuretask的核心方法

可通過將futuretask放入乙個執行緒,或者將其放入執行緒池中實現呼叫。其中set()和setexception()會喚醒存在waiters中的node,告訴他們計算已經完成,或者計算中丟擲了異常。

在set()、setexception()和cancel()方法的末尾都會呼叫finishcompletion()方法來釋放存在waiters中的執行緒,在該方法中還有乙個done()方法,用來讓子類實現,做一些非同步任務完成之後的事情。

看看cancel()方法

需要注意的是任務只有在state == new的時候才能被取消。

futuretask可通過get()呼叫得到計算的結果,如果計算還沒完成,該方法會阻塞,也可響應中斷。產生阻塞的時候會將執行緒wrap成node加入到waiters中。下面看看get中呼叫的awaitdone(boolean timed, long nanos)方法

awaitdone**中採取死迴圈的方式:

檢查是否響應中斷,若是,則移除該node,丟擲中斷異常。

if (thread.interrupted())
若此時已經結束,返回此時的狀態值。

int s = state;

if (s > completing)

若判斷為以下情況則暫時讓出cpu時間,稍後執行,因為completing是乙個瞬時的狀態,說明這個時候計算結果已經馬上要被set了,或者也可能是丟擲了異常。

else if (s == completing) // cannot time out yet

thread.yield();

若判斷為以下情況則新建乙個node,該node包裝了當前的執行緒。

else if (q == null)

q = new waitnode()

若判斷為以下情況則將node加入到waiters中

else if (!queued)

queued = unsafe.compareandswapobject(this, waitersoffset, q.next = waiters, q);

接下來最後的兩個判斷都是park這個執行緒,只是有時間的區分。

利用futuretask和executorservice,可以用多執行緒的方式提交計算任務,主線程繼續執行其他任務,當主線程需要子執行緒的計算結果時,在非同步獲取子執行緒的執行結果。

個人管理 個人知識管理

持續的學習是個人生存和發展的基礎 資訊和知識 在一段時間和時期內,學習的內容必須聚焦,起碼要在乙個領域內成為專家學習的內容取決於個人的價值觀 特長 個性和目標人是知識獲取的重要渠道,所以你應該知道誰最擅長什麼?遇到問題時知道可以向誰學習和請教人際關係需要維護,捷徑是找到那些願意共享自己朋友資源的人,...

個人管理 個人知識管理

持續的學習是個人生存和發展的基礎 資訊和知識 在一段時間和時期內,學習的內容必須聚焦,起碼要在乙個領域內成為專家學習的內容取決於個人的價值觀 特長 個性和目標人是知識獲取的重要渠道,所以你應該知道誰最擅長什麼?遇到問題時知道可以向誰學習和請教人際關係需要維護,捷徑是找到那些願意共享自己朋友資源的人,...

個人管理 個人知識管理

持續的學習是個人生存和發展的基礎 資訊和知識 在一段時間和時期內,學習的內容必須聚焦,起碼要在乙個領域內成為專家學習的內容取決於個人的價值觀 特長 個性和目標人是知識獲取的重要渠道,所以你應該知道誰最擅長什麼?遇到問題時知道可以向誰學習和請教人際關係需要維護,捷徑是找到那些願意共享自己朋友資源的人,...