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

Java調(diào)度線程池ScheduledThreadPoolExecutor不執(zhí)行問題分析

 更新時(shí)間:2023年03月02日 10:07:29   作者:Redick01  
最近項(xiàng)目上反饋某個(gè)重要的定時(shí)任務(wù)突然不執(zhí)行了,很頭疼,開發(fā)環(huán)境和測(cè)試環(huán)境都沒有出現(xiàn)過這個(gè)問題。定時(shí)任務(wù)采用的是ScheduledThreadPoolExecutor,后來一看代碼發(fā)現(xiàn)踩了一個(gè)大坑。本文就來和大家聊聊這次的踩坑記錄與解決方法,需要的可以參考一下

前言

最近在調(diào)試一個(gè)監(jiān)控應(yīng)用指標(biāo)的時(shí)候發(fā)現(xiàn)定時(shí)器在服務(wù)啟動(dòng)執(zhí)行一次之后就不執(zhí)行了,這里用的定時(shí)器是Java的調(diào)度線程池ScheduledThreadPoolExecutor,后來經(jīng)過排查發(fā)現(xiàn)ScheduledThreadPoolExecutor線程池處理任務(wù)如果拋出異常,會(huì)導(dǎo)致線程池不調(diào)度;下面就通過一個(gè)例子簡(jiǎn)單分析下為什么異常會(huì)導(dǎo)致ScheduledThreadPoolExecutor不執(zhí)行。

ScheduledThreadPoolExecutor不調(diào)度分析

示例程序

在示例程序可以看到當(dāng)計(jì)數(shù)器中的計(jì)數(shù)達(dá)到5的時(shí)候就會(huì)主動(dòng)拋出一個(gè)異常,拋出異常后ScheduledThreadPoolExecutor就不調(diào)度了。

public class ScheduledTask {
    private static final AtomicInteger count = new AtomicInteger(0);
    private static final ScheduledThreadPoolExecutor SCHEDULED_TASK = new ScheduledThreadPoolExecutor(
            1, new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(Thread.currentThread().getThreadGroup(), r, "sc-task");
            t.setDaemon(true);
            return t;
        }
    });
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        SCHEDULED_TASK.scheduleWithFixedDelay(() -> {
            System.out.println(111);
            if (count.get() == 5) {
                throw new IllegalArgumentException("my exception");
            }
            count.incrementAndGet();
        }, 0, 5, TimeUnit.SECONDS);
        latch.await();
    }
}

源碼分析

ScheduledThreadPoolExecutor#run

run方法內(nèi)部首先判斷任務(wù)是不是周期性的任務(wù),如果不是周期性任務(wù)通過ScheduledFutureTask.super.run();執(zhí)行任務(wù);如果狀態(tài)是運(yùn)行中或shutdown,取消任務(wù)執(zhí)行;如果是周期性的任務(wù),通過ScheduledFutureTask.super.runAndReset()執(zhí)行任務(wù)并且重新設(shè)置狀態(tài),成功了就會(huì)執(zhí)行setNextRunTime設(shè)置下次調(diào)度的時(shí)間,問題就是出現(xiàn)在ScheduledFutureTask.super.runAndReset(),這里執(zhí)行任務(wù)出現(xiàn)了異常,導(dǎo)致結(jié)果為false,就不進(jìn)行下次調(diào)度時(shí)間設(shè)置等

        public void run() {
            boolean periodic = isPeriodic();
            if (!canRunInCurrentRunState(periodic))
                cancel(false);
            else if (!periodic)
                ScheduledFutureTask.super.run();
            else if (ScheduledFutureTask.super.runAndReset()) {
                setNextRunTime();
                reExecutePeriodic(outerTask);
            }
        }

*FutureTask#runAndReset

在線程任務(wù)執(zhí)行過程中拋出異常,然后catch到了異常,最終導(dǎo)致這個(gè)方法返回false,然后ScheduledThreadPoolExecutor#run就不設(shè)置下次執(zhí)行時(shí)間了,代碼c.call(); 拋出異常,跳過ran = true;代碼,最終runAndReset返回false。

    protected boolean runAndReset() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return false;
        boolean ran = false;
        int s = state;
        try {
            Callable<V> c = callable;
            if (c != null && s == NEW) {
                try {
                    c.call(); // don't set result
                    ran = true;
                } catch (Throwable ex) {
                    setException(ex);
                }
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
        return ran && s == NEW;
    }

總結(jié)

Java的ScheduledThreadPoolExecutor定時(shí)任務(wù)線程池所調(diào)度的任務(wù)中如果拋出了異常,并且異常沒有捕獲直接拋到框架中,會(huì)導(dǎo)致ScheduledThreadPoolExecutor定時(shí)任務(wù)不調(diào)度了,具體是因?yàn)楫?dāng)異常拋到ScheduledThreadPoolExecutor框架中時(shí)不進(jìn)行下次調(diào)度時(shí)間的設(shè)置,從而導(dǎo)致ScheduledThreadPoolExecutor定時(shí)任務(wù)不調(diào)度。

到此這篇關(guān)于Java調(diào)度線程池ScheduledThreadPoolExecutor不執(zhí)行問題分析的文章就介紹到這了,更多相關(guān)Java ScheduledThreadPoolExecutor內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中Flux類的使用方法和示例代碼

    Java中Flux類的使用方法和示例代碼

    在Java編程中Flux是一種處理響應(yīng)式編程的庫(kù),它提供了一種異步數(shù)據(jù)流處理的方式,這篇文章主要給大家介紹了關(guān)于Java中Flux類的使用方法和示例代碼,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • 詳解eclipse中Maven工程使用Tomcat7以上插件的方法

    詳解eclipse中Maven工程使用Tomcat7以上插件的方法

    本篇文章主要介紹了詳解eclipse中Maven工程使用Tomcat7以上插件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • 解決springboot啟動(dòng)報(bào)錯(cuò)bean找不到的問題

    解決springboot啟動(dòng)報(bào)錯(cuò)bean找不到的問題

    這篇文章主要介紹了解決springboot啟動(dòng)報(bào)錯(cuò)bean找不到原因,本文給大家分享完美解決方案,通過圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • springBoot無法解析yml問題

    springBoot無法解析yml問題

    這篇文章主要介紹了springBoot無法解析yml問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Springboot?整合maven插口調(diào)用maven?release?plugin實(shí)現(xiàn)一鍵打包功能

    Springboot?整合maven插口調(diào)用maven?release?plugin實(shí)現(xiàn)一鍵打包功能

    這篇文章主要介紹了Springboot?整合maven插口調(diào)用maven?release?plugin實(shí)現(xiàn)一鍵打包功能,整合maven-invoker使程序去執(zhí)行mvn命令,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • MyBatis-Plus 與Druid 數(shù)據(jù)源操作

    MyBatis-Plus 與Druid 數(shù)據(jù)源操作

    SpringBoot框架集成MyBatis-Plus和Druid數(shù)據(jù)源,簡(jiǎn)化了數(shù)據(jù)操作與監(jiān)控,MyBatis-Plus作為MyBatis的增強(qiáng)工具,自動(dòng)實(shí)現(xiàn)CRUD操作,減少手寫SQL,提供分頁、邏輯刪除等功能,本文介紹MyBatis-Plus & Druid 數(shù)據(jù)源總結(jié),感興趣的朋友一起看看吧
    2024-09-09
  • Springdoc替換swagger的實(shí)現(xiàn)步驟分解

    Springdoc替換swagger的實(shí)現(xiàn)步驟分解

    最近在spring看到的,spring要對(duì)api文檔動(dòng)手了,有些人說swagger不好用,其實(shí)也沒那么不好用,有人說代碼還是有點(diǎn)侵入性,這倒是真的,我剛試了springdoc可以說還是有侵入性但是也可以沒有侵入性,這就看你對(duì)文檔有什么要求了
    2023-02-02
  • Java使用JSONObject操作json實(shí)例解析

    Java使用JSONObject操作json實(shí)例解析

    這篇文章主要介紹了Java使用JSONObject操作json,結(jié)合實(shí)例形式較為詳細(xì)的分析了Java使用JSONObject解析json數(shù)據(jù)相關(guān)原理、使用技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • Spring Security+JWT實(shí)現(xiàn)認(rèn)證與授權(quán)的實(shí)現(xiàn)

    Spring Security+JWT實(shí)現(xiàn)認(rèn)證與授權(quán)的實(shí)現(xiàn)

    本文主要介紹了Spring Security+JWT實(shí)現(xiàn)認(rèn)證與授權(quán)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Java設(shè)計(jì)模式之適配器模式詳解

    Java設(shè)計(jì)模式之適配器模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之適配器模式詳解,適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另一個(gè)接口,Adapter模式使得原本由于接口不兼容而不能一起工作的哪些類可以一起工作,需要的朋友可以參考下
    2023-09-09

最新評(píng)論

南充市| 扎鲁特旗| 九江县| 苗栗县| 建阳市| 方正县| 建阳市| 南江县| 株洲市| 抚州市| 齐河县| 广宁县| 秭归县| 怀宁县| 肇州县| 岱山县| 泸溪县| 拜泉县| 岑巩县| 建平县| 淄博市| 酒泉市| 祁门县| 正镶白旗| 武安市| 汪清县| 商南县| 新龙县| 新密市| 江安县| 江川县| 清苑县| 临西县| 米泉市| 临洮县| 彩票| 万全县| 汨罗市| 涟水县| 抚松县| 涞源县|