日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

之前在實現(xiàn)熔斷降級組件時,需要實現(xiàn)一個接口的超時中斷,意思是,業(yè)務在使用熔斷降級功能時,在平臺上設置了一個超時時間,如果在請求進入熔斷器開始計時,并且接口在超時時間內沒有響應,則需要提早中斷該請求并返回。

比如正常下游接口的超時時間為800ms,但是因為自身業(yè)務的特殊需求,最多只能等200ms,如果200ms之內沒有數(shù)據(jù)返回,則返回降級數(shù)據(jù)。這里處理請求的線程可以看成是Tomcat線程池中的一個線程,如果通過線程池返回的Future,可以很輕松的實現(xiàn)超時返回,但是這種情況下,并不能拿到Futrue,需要換一種思路。

Java中如何實現(xiàn)線程的超時中斷

 

思路

中斷一個線程的思路有哪些?

除了已經(jīng)廢棄的Thread.stop, Thread.suspend, Thread.resume 方法,剩下的貌似只有一種方案了,就是調用當前線程的interrupt(),但是這個方法的作用并不是中斷線程,而是設置一個標識,通知該線程可以被中斷了,到底是繼續(xù)執(zhí)行,還是中斷返回,由線程本身自己決定。

具體來說,當對一個線程調用了interrupt()之后,如果該線程處于被阻塞狀態(tài)(比如執(zhí)行了wait、sleep或join等方法),那么會立即退出阻塞狀態(tài),并拋出一個InterruptedException異常,在代碼中catch這個異常進行后續(xù)處理。如果線程一直處于運行狀態(tài),那么只會把該線程的中斷標志設置為 true,僅此而已,所以interrupt()并不能真正的中斷線程,不過在rpc調用的場景中,請求線程一般都處于阻塞狀態(tài),等待數(shù)據(jù)返回,這時interrupt()方法是可以派上用場的。

那么,要實現(xiàn)指定超時時間內中斷請求線程,還有最后一個問題需要解決:什么時候,由誰去執(zhí)行interrupt()方法?

必然這個方法只能由其它線程來執(zhí)行了(自己都阻塞了,執(zhí)行個鬼),而且是在請求進入熔斷器時,并在超時時間之后執(zhí)行,有點繞,比如超時時間是200ms,那么請求進入熔斷器之后,再過200ms,就執(zhí)行interrupt(),但是在200ms之內有數(shù)據(jù)返回,那么就不執(zhí)行interrupt()了。

實現(xiàn)

需求已經(jīng)很明確了,相當于延遲執(zhí)行一個task,其內部邏輯就是執(zhí)行請求線程的interrupt(),當然還有其它的邏輯。

Runnable task = new Runnable() {

@Override

public void run() {

try {

thread.interrupt();

// 取消定時器任務

f.cancel();

} catch (Exception e) {

logger.error("Failed while ticking TimerListener", e);

}

}

};

Doug Lea大神提供的ScheduledThreadPoolExecutor可以很好的滿足這個需求,通過scheduleAtFixedRate方法可以很方便的實現(xiàn)在延遲指定時間之后執(zhí)行提交的任務。

ScheduledFuture<?> f = executor.scheduleAtFixedRate(
task, timeout, timeout, TimeUnit.MILLISECONDS);

在請求進入熔斷器時,順便提交一個任務到線程池中等待執(zhí)行,如果接口在超時時間內沒有返回,那么該任務會被觸發(fā),并執(zhí)行請求線程的interrupt方法,這樣就實現(xiàn)了請求線程的中斷(因為這時請求線程正在被阻塞,等待數(shù)據(jù)返回),另外需要清空定時任務,不然這個任務會一直執(zhí)行。

如果接口正常返回了,也要記得清空定時任務,并且在請求退出熔斷器的時候,記得恢復請求線程的中斷標識,如何恢復?在請求線程中執(zhí)行下面代碼即可。

Thread.interrupted();
// 內部邏輯
public static boolean interrupted() {
 return currentThread().isInterrupted(true);
}
// 參數(shù)為true,可以清除中斷標識
private native boolean isInterrupted(boolean ClearInterrupted);

執(zhí)行當前線程(即請求線程)的isInterrupted方法。

使用這種方式實現(xiàn)請求的超時中斷,在QPS很高的情況下,會有額外的性能損失,因為每次請求都要提交一個任務到線程池中等待執(zhí)行。

分享到:
標簽:超時 中斷 Java
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定