欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

ScheduledThreadPoolExecutor不調(diào)度分析

示例程序

在示例程序可以看到當(dāng)計數(shù)器中的計數(shù)達到5的時候就會主動拋出一個異常,拋出異常后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)是運行中或shutdown,取消任務(wù)執(zhí)行;如果是周期性的任務(wù),通過ScheduledFutureTask.super.runAndReset()執(zhí)行任務(wù)并且重新設(shè)置狀態(tài),成功了就會執(zhí)行setNextRunTime設(shè)置下次調(diào)度的時間,問題就是出現(xiàn)在ScheduledFutureTask.super.runAndReset(),這里執(zhí)行任務(wù)出現(xiàn)了異常,導(dǎo)致結(jié)果為false,就不進行下次調(diào)度時間設(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)致這個方法返回false,然后ScheduledThreadPoolExecutor#run就不設(shè)置下次執(zhí)行時間了,代碼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定時任務(wù)線程池所調(diào)度的任務(wù)中如果拋出了異常,并且異常沒有捕獲直接拋到框架中,會導(dǎo)致ScheduledThreadPoolExecutor定時任務(wù)不調(diào)度了,具體是因為當(dāng)異常拋到ScheduledThreadPoolExecutor框架中時不進行下次調(diào)度時間的設(shè)置,從而導(dǎo)致ScheduledThreadPoolExecutor定時任務(wù)不調(diào)度。

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

相關(guān)文章

  • java線性表排序示例分享

    java線性表排序示例分享

    這篇文章主要介紹了java線性表排序示例,需要的朋友可以參考下
    2014-03-03
  • 使用IDEA配置Maven搭建開發(fā)框架ssm教程

    使用IDEA配置Maven搭建開發(fā)框架ssm教程

    這篇文章主要為大家詳細介紹了使用IDEA配置Maven搭建開發(fā)框架ssm教程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Springboot如何通過路徑映射獲取本機圖片資源

    Springboot如何通過路徑映射獲取本機圖片資源

    項目中對圖片的處理與查看是必不可少的,本文將講解如何通過項目路徑來獲取到本機電腦的圖片資源,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-08-08
  • Java數(shù)據(jù)結(jié)構(gòu)之鏈表(動力節(jié)點之Java學(xué)院整理)

    Java數(shù)據(jù)結(jié)構(gòu)之鏈表(動力節(jié)點之Java學(xué)院整理)

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之鏈表(動力節(jié)點之Java學(xué)院整理)的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Springboot中如何使用過濾器校驗PSOT類型請求參數(shù)內(nèi)容

    Springboot中如何使用過濾器校驗PSOT類型請求參數(shù)內(nèi)容

    在Springboot中創(chuàng)建過濾器,用來過濾所有POST類型請求并獲取body中的參數(shù)進行校驗內(nèi)容是否合法,該方法僅適用于POST類型請求,本文給大家介紹Springboot中如何使用過濾器校驗PSOT類型請求參數(shù)內(nèi)容,感興趣的朋友一起看看吧
    2023-08-08
  • SpringBoot中@EnableAsync和@Async注解的使用小結(jié)

    SpringBoot中@EnableAsync和@Async注解的使用小結(jié)

    在SpringBoot中,可以通過@EnableAsync注解來啟動異步方法調(diào)用的支持,通過@Async注解來標(biāo)識異步方法,讓方法能夠在異步線程中執(zhí)行,本文就來介紹一下,感興趣的可以了解一下
    2023-11-11
  • 深入了解JVM字節(jié)碼增強技術(shù)

    深入了解JVM字節(jié)碼增強技術(shù)

    這篇文章主要介紹了深入了解JVM字節(jié)碼增強技術(shù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Java中使用BeanMap將對象轉(zhuǎn)為Map詳解

    Java中使用BeanMap將對象轉(zhuǎn)為Map詳解

    這篇文章主要介紹了Java中使用BeanMap將對象轉(zhuǎn)為Map詳解,BeanMap?是?Apache?Commons?BeanUtils?庫中的一個類,BeanMap?可以將?Java?對象的屬性作為鍵,屬性值作為對應(yīng)的值,存儲在一個?Map?中,它提供了一種將?Java?對象轉(zhuǎn)換為?Map?的方式,需要的朋友可以參考下
    2024-01-01
  • SpringBoot實現(xiàn)數(shù)據(jù)加密脫敏的示例代碼

    SpringBoot實現(xiàn)數(shù)據(jù)加密脫敏的示例代碼

    這篇文章主要為大家學(xué)習(xí)介紹了SpringBoot如何利用注解+反射+AOP實現(xiàn)數(shù)據(jù)加密脫敏的功能,文中的示例代碼講解詳細,需要的可以參考一下
    2023-08-08
  • 如何利用SpringBoot搭建WebService服務(wù)接口

    如何利用SpringBoot搭建WebService服務(wù)接口

    之前項目經(jīng)理想要開發(fā)一個webservice的協(xié)議,給我一個星期的時間,后面用springboot開發(fā)了webservice,這篇文章主要給大家介紹了關(guān)于如何利用SpringBoot搭建WebService服務(wù)接口的相關(guān)資料,需要的朋友可以參考下
    2023-11-11

最新評論