最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中實(shí)現(xiàn)線程的超時(shí)中斷方法實(shí)例

 更新時(shí)間:2018年06月21日 08:20:55   作者:占小狼  
之前在使用Java實(shí)現(xiàn)熔斷降級(jí)組件的時(shí)候,需要實(shí)現(xiàn)接口請(qǐng)求的超時(shí)中斷,通過(guò)查找相關(guān)資料了解了相關(guān)的方法,下面這篇文章主要給大家介紹了關(guān)于Java中實(shí)現(xiàn)線程的超時(shí)中斷的相關(guān)資料,需要的朋友可以參考下

背景

之前在實(shí)現(xiàn)熔斷降級(jí)組件時(shí),需要實(shí)現(xiàn)一個(gè)接口的超時(shí)中斷,意思是,業(yè)務(wù)在使用熔斷降級(jí)功能時(shí),在平臺(tái)上設(shè)置了一個(gè)超時(shí)時(shí)間,如果在請(qǐng)求進(jìn)入熔斷器開(kāi)始計(jì)時(shí),并且接口在超時(shí)時(shí)間內(nèi)沒(méi)有響應(yīng),則需要提早中斷該請(qǐng)求并返回。

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

思路

中斷一個(gè)線程的思路有哪些?

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

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

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

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

實(shí)現(xiàn)

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

Runnable task = new Runnable() {
 @Override
 public void run() {
  try {
   thread.interrupt();
   // 取消定時(shí)器任務(wù)
   f.cancel();
  } catch (Exception e) {
   logger.error("Failed while ticking TimerListener", e);
  }
 }
};

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

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

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

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

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

執(zhí)行當(dāng)前線程(即請(qǐng)求線程)的isInterrupted方法。

使用這種方式實(shí)現(xiàn)請(qǐng)求的超時(shí)中斷,在QPS很高的情況下,會(huì)有額外的性能損失,因?yàn)槊看握?qǐng)求都要提交一個(gè)任務(wù)到線程池中等待執(zhí)行。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • spring boot注解方式使用redis緩存操作示例

    spring boot注解方式使用redis緩存操作示例

    這篇文章主要介紹了spring boot注解方式使用redis緩存操作,結(jié)合實(shí)例形式分析了spring boot注解方式使用redis緩存相關(guān)的依賴庫(kù)引入、注解使用及redis緩存相關(guān)操作技巧,需要的朋友可以參考下
    2019-11-11
  • Java日期時(shí)間字符串和毫秒相互轉(zhuǎn)換的方法

    Java日期時(shí)間字符串和毫秒相互轉(zhuǎn)換的方法

    這篇文章主要為大家詳細(xì)介紹了Java日期時(shí)間字符串和毫秒相互轉(zhuǎn)換的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • java List集合接口的介紹和使用全面教程

    java List集合接口的介紹和使用全面教程

    這篇文章主要為大家介紹了java List集合接口的介紹和使用全面教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Java異常處理機(jī)制try catch流程詳解

    Java異常處理機(jī)制try catch流程詳解

    這篇文章主要介紹了Java異常處理機(jī)制try catch流程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • mac系統(tǒng)如何下載和安裝jdk的三種方式

    mac系統(tǒng)如何下載和安裝jdk的三種方式

    這篇文章主要介紹了mac系統(tǒng)下載和安裝jdk的三種方式,每種方法都有其特點(diǎn),如安裝來(lái)源及可靠性、安裝過(guò)程及便捷性、版本管理及切換、環(huán)境配置、jdk默認(rèn)安裝路徑以及占用空間及資源管理等,需要的朋友可以參考下
    2025-01-01
  • Mybatis批量提交實(shí)現(xiàn)步驟詳解

    Mybatis批量提交實(shí)現(xiàn)步驟詳解

    這篇文章主要介紹了Mybatis批量提交實(shí)現(xiàn)步驟詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java中的interrupted()和isInterrupted()

    Java中的interrupted()和isInterrupted()

    這篇文章主要介紹了Java中的interrupted()和isInterrupted()摸下面文章圍繞interrupted()和isInterrupted()的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,需要的小伙伴樂(lè)意參考下面下面文章具體價(jià)紹,希望對(duì)大家有所幫助
    2021-11-11
  • 如何實(shí)現(xiàn)廣告彈窗觸達(dá)頻率的控制?

    如何實(shí)現(xiàn)廣告彈窗觸達(dá)頻率的控制?

    這篇文章主要介紹了如何實(shí)現(xiàn)廣告彈窗觸達(dá)頻率的控制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Java簡(jiǎn)單統(tǒng)計(jì)字符串中漢字,英文字母及數(shù)字?jǐn)?shù)量的方法

    Java簡(jiǎn)單統(tǒng)計(jì)字符串中漢字,英文字母及數(shù)字?jǐn)?shù)量的方法

    這篇文章主要介紹了Java簡(jiǎn)單統(tǒng)計(jì)字符串中漢字,英文字母及數(shù)字?jǐn)?shù)量的方法,涉及java針對(duì)字符串的遍歷、編碼轉(zhuǎn)換、判斷等相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • 如何在Spring data中使用r2dbc詳解

    如何在Spring data中使用r2dbc詳解

    這篇文章主要給大家介紹了關(guān)于如何在Spring data中使用r2dbc的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論

沙雅县| 乐都县| 龙海市| 青海省| 武城县| 平江县| 岳阳县| 甘南县| 乌拉特前旗| 迁西县| 湘西| 山阳县| 水富县| 兴海县| 江津市| 松江区| 麻阳| 嘉鱼县| 安国市| 冷水江市| 夏津县| 博客| 彭州市| 临西县| 菏泽市| 乡宁县| 武宣县| 易门县| 峡江县| 工布江达县| 四会市| 和硕县| 东城区| 黄浦区| 宣城市| 桑植县| 大邑县| 崇左市| 八宿县| 陇西县| 五原县|