国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

任務(wù)異常導(dǎo)致線程池中的線程變?yōu)閣aiting狀態(tài)

fyber / 2456人閱讀

摘要:通過搜索引擎了解到以下觀點提交到線程池的任務(wù)如果拋出異常會導(dǎo)致線程掛掉,遂將提交到線程池的任務(wù)中可能出現(xiàn)的異常進行了處理,確實解決了問題。

背景

項目中存在一些定時任務(wù)來更新數(shù)據(jù)庫表,借助了線程池提供的一些能力,線上環(huán)境偶爾會出現(xiàn)網(wǎng)絡(luò)波動導(dǎo)致服務(wù)實例無法連上數(shù)據(jù)庫,只要出現(xiàn)了這種情況,就會導(dǎo)致數(shù)據(jù)不會再被更新,通過一些命令發(fā)現(xiàn)更新數(shù)據(jù)庫的線程池中的所有線程都處于waiting狀態(tài)。通過搜索引擎了解到以下觀點:提交到線程池的任務(wù)如果拋出異常會導(dǎo)致線程掛掉,遂將提交到線程池的任務(wù)中可能出現(xiàn)的異常進行了處理,確實解決了問題。
同時也留下了一個疑問:為什么任務(wù)拋出的異常會導(dǎo)致線程處于waiting狀態(tài)?

本篇文章的關(guān)注點主要集中在ScheduledThreadPoolExecutor.scheduleWithFixedDelay(..)這個方法上,對線程池的一些原理性的內(nèi)容以及相關(guān)的術(shù)語不做過多描述。
執(zhí)行流程

scheduleWithFixedDelay(..) 的大體運行過程(注,ScheduledThreadPoolExecutor類中還包含了execute,submit,schedule等方法,這些方法的邏輯基本是一致的):
1、首先對提交的任務(wù)(Runnable實例)進行一些包裝,生成一個ScheduledFutureTask:

2、進入delayedExecute(..)方法,將生成的ScheduledFutureTask 放到線程池的任務(wù)隊列(注:BlockingQueue)中;

3、進入ensurePrestart()方法,創(chuàng)建Worker實例開始處理線程:

4、最后就是addWorker方法了,此方法主要關(guān)注以下部分:

到這里,線程池中已經(jīng)創(chuàng)建了線程,并且開始執(zhí)行了。接下來就看看Worker線程是如何執(zhí)行提交到線程池中的任務(wù)的。
5、上一步中,可以看到Worker中持有的線程已經(jīng)開始運行了,而Worker中的線程是這么創(chuàng)建的:

所以,Worker中的線程start之后,則開始執(zhí)行Worker中的run()方法(會進入到runWorker(..)方法)
6、上面的第1、2步中,會把構(gòu)造的ScheduledFutureTask實例放到任務(wù)隊列中,這里會再從任務(wù)隊列中取出該實例(圖中的while循環(huán)條件),然后再去調(diào)用該實例的run()方法:

getTask()方法:

7、ScheduledThreadPoolExecutor.ScheduledFutureTask#run()方法:

這里的outerTask就是第1步中的outerTask,其實就是要執(zhí)行的任務(wù)本身。到了這里給出一個小結(jié):對于周期性執(zhí)行的任務(wù),如果該任務(wù)執(zhí)行失敗,則后續(xù)其不會再被執(zhí)行。
為了內(nèi)容的完整性,下面給出上圖中兩個方法的流程:

到此,任務(wù)異常導(dǎo)致線程waiting的原因就明了了:
由于任務(wù)執(zhí)行過程中拋出了異常,會造成ScheduledFutureTask不會再將自身放入到任務(wù)隊列(BlockingQueue)中,即執(zhí)行完之后,任務(wù)隊列變成了一個空隊列,而線程池中的Worker線程會以阻塞的方式從任務(wù)隊列中去取任務(wù)(第6步),當(dāng)隊列為空時,會導(dǎo)致所有的線程都被阻塞而進入waiting狀態(tài)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/77534.html

相關(guān)文章

  • 一個線程罷工的詭異事件

    摘要:結(jié)合之前的線程快照,我發(fā)現(xiàn)這個消費線程也是處于狀態(tài),和后面的業(yè)務(wù)線程池一模一樣。本地模擬本地也是創(chuàng)建了一個單線程的線程池,分別執(zhí)行了兩個任務(wù)。發(fā)現(xiàn)當(dāng)任務(wù)中拋出一個沒有捕獲的異常時,線程池中的線程就會處于狀態(tài),同時所有的堆棧都和生產(chǎn)相符。 showImg(https://segmentfault.com/img/remote/1460000018482477); 背景 事情(事故)是這樣...

    BakerJ 評論0 收藏0
  • 線程池沒你想的那么簡單(續(xù))

    摘要:前言前段時間寫過一篇線程池沒你想的那么簡單,和大家一起擼了一個基本的線程池,具備線程池基本調(diào)度功能。線程池自動擴容縮容。回調(diào)以上就是線程池的構(gòu)造函數(shù)以及接口的定義。所以我們在使用線程池時,其中的任務(wù)一定要做好異常處理。線程異常捕獲的重要性。 showImg(https://segmentfault.com/img/remote/1460000019403163?w=1904&h=108...

    svtter 評論0 收藏0
  • java并發(fā)編程學(xué)習(xí)1--基礎(chǔ)知識

    摘要:死亡狀態(tài)線程退出有可能是正常執(zhí)行完成也有可能遇見異常退出。類有新建與死亡狀態(tài)返回其余狀態(tài)返回判斷線程是否存活。線程因某些原因進入阻塞狀態(tài)。執(zhí)行同步代碼塊的過程中執(zhí)行了當(dāng)前線程放棄開始睡眠進入就緒狀態(tài)但是不會釋放鎖。 【java內(nèi)存模型簡介 JVM中存在一個主存區(qū)(Main Memory或Java Heap Memory),Java中所有變量都是存在主存中的,對于所有線程進行共享,而每個...

    huangjinnan 評論0 收藏0
  • Java并發(fā)總結(jié)

    摘要:限期阻塞調(diào)用方法等待時間結(jié)束或線程執(zhí)行完畢。終止?fàn)顟B(tài)線程執(zhí)行完畢或出現(xiàn)異常退了。和都會檢查線程何時中斷,并且在發(fā)現(xiàn)中斷時提前放回。工廠方法將線程池的最大大小設(shè)置為,而將基本大小設(shè)置為,并將超時大小設(shè)置為分鐘。 wait()、notify()、notifyAll() Object是所有類的基類,它有5個方法組成了等待、通知機制的核心:notify()、notifyAll()、wait()...

    szysky 評論0 收藏0
  • 線程小記

    摘要:死亡狀態(tài)有兩個原因會導(dǎo)致線程死亡方法正常退出而自然死亡。一個未捕獲的異常終止了方法而使線程猝死。注意,放入的線程不必?fù)?dān)心其結(jié)束,超過不活動,其會自動被終止。線程間相互干擾描述了當(dāng)多個線程訪問共享數(shù)據(jù)時可能出現(xiàn)的錯誤。 線程 進程與線程的區(qū)別 線程是指進程內(nèi)的一個執(zhí)行單元,也是進程內(nèi)的可調(diào)度實體。一個程序至少有一個進程,一個進程至少有一個線程。 線程的五大狀態(tài) 新建狀態(tài)(New):例如...

    suxier 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<