Java定時執行緒池停止超時任務

2021-08-21 05:18:39 字數 1390 閱讀 7174

題主最近遇到乙個問題,本來通過scheduledexecutorservice執行緒池定時排程乙個任務。奈何不知道為啥跑了2個多月,其中乙個任務hang住了,原本定時的任務則出現了問題。

關於定時執行緒池,好多人認為設定好頻率(比如1min),它會按照這個間隔按部就班的工作。但是,如果其中一次排程任務卡住的話,不僅這次排程失敗,而且整個執行緒池也會停在這次排程上。

我們先從乙個例子試著復現下問題:

public

class

pool catch (exception e) }}

public

static

void

main(string args)

}

先從main看,啟動乙個定時執行緒池,每隔1s排程一次runner。看上去,應該是1s排程一次,但是runner的實際執行時間為10s,那多久會排程一次?答案是10s。

所以說,這個runner不管什麼原因掛掉了或者hang住了,那這個定時排程執行緒池基本就廢了。

那我們應該怎麼解決這個問題?如果說定時執行緒池有任務排程的超時策略就完美了,很可惜並沒有。

我們想下在併發程式設計中,哪種方式有超時策略?

對,future有,那我們可以結合future,提供一種自動停止超時任務的方式,來解決某個任務hang住的問題。

我們簡單修改下,把sleep邏輯移動到callable中,並在runner中使用future來控制超時。

public

class

pool catch (exception e)

return

false;}}

private

static

class

runner

implements

runnable catch (timeoutexception e) catch (exception e) finally }}

public

static void main(string args)

}

備註:

- 實現邏輯相當於轉移了,把本來應該排程的任務交給了另外乙個future單執行緒去執行。因為存在超時邏輯,不會影響原有定時執行緒池的執行。

- finally是否需要殺死執行緒池,因人而異。如果不殺死的話,那超時的任務會繼續執行。

定時任務 內部類 執行緒池

需求 把每天的資料定時推送到第三方,資料量有點大,如果乙個個推送資料,需要耗時非常久,所以採取執行緒池 內部類操作。1.首先先了解一下定時任務cron的寫法。cron表示式是乙個字串,字串以5或6個空格隔開,分為6或7個域。cron從左到右 用空格隔開 秒 分 小時 月份中的日期 月份 星期中的日期...

8 併發程式設計 定時任務 定時執行緒池

scheduledthreadpoolexecutor 用來處理延時任務或定時任務。它接收schduledfuturetask型別的任務,是執行緒池排程任務的最小單位,有三種提交任務的方式 schedule scheduledatfixedrate scheduledwithfixeddelay 它...

Quartz定時任務框架執行緒池

springboot使用 enablescheduling註解開啟定時任務功能後,預設建立乙個固定執行緒數為1的執行緒池給定時任務框架呼叫執行定時任務。當多個任務同時執行時,會導致多個任務競爭執行執行緒,當上乙個任務執行完畢後,執行緒才會被釋放出來用於其他任務的執行。導致定時任務延時執行。因此需要建...