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

一文帶你學(xué)會(huì)Java中ScheduledThreadPoolExecutor使用

 更新時(shí)間:2024年12月15日 11:06:48   作者:JWASX  
ScheduledThreadPoolExecutor是Java并發(fā)包中的一個(gè)類,同時(shí)也是?ThreadPoolExecutor的一個(gè)子類,本文主要為大家介紹一下ScheduledThreadPoolExecutor使用,需要的可以參考下

1. 概要

前面文章的地址:

定時(shí)/延時(shí)任務(wù)-自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的定時(shí)器

定時(shí)/延時(shí)任務(wù)-Timer用法

ScheduledThreadPoolExecutor 是 Java 并發(fā)包 (java.util.concurrent) 中的一個(gè)類,同時(shí)也是 ThreadPoolExecutor 的一個(gè)子類,這就意味者 ScheduledThreadPoolExecutor 不像 Timer 中使用單個(gè)線程去執(zhí)行任務(wù),ScheduledThreadPoolExecutor 使用了線程池去執(zhí)行,同時(shí) ScheduledThreadPoolExecutor 也具備了 Timer 中的各種功能。

2. 固定速率和固定延時(shí)

2.1 固定速率

固定速率 策略表示任務(wù)在固定的時(shí)間間隔內(nèi)重復(fù)執(zhí)行,不管任務(wù)的執(zhí)行時(shí)間有多長(zhǎng),如果任務(wù)的執(zhí)行時(shí)間超過了時(shí)間間隔,那么下一個(gè)任務(wù)會(huì)在當(dāng)前任務(wù)執(zhí)行完畢之后就會(huì)馬上開始執(zhí)行,下面是一個(gè)例子:假設(shè)我們?cè)O(shè)置了一個(gè)固定速率為 5 的任務(wù),從 0s 開始執(zhí)行,也就是說這個(gè)任務(wù) 5s 執(zhí)行一次:

  • 第一次執(zhí)行: 在 0s 開始執(zhí)行一次,假設(shè)執(zhí)行時(shí)間是 3s
  • 第二次執(zhí)行: 在 5s 開始執(zhí)行第二次,假設(shè)執(zhí)行的時(shí)候被阻塞了,執(zhí)行了 8s
  • 第三次執(zhí)行: 在 13s 開始執(zhí)行第三次,假設(shè)執(zhí)行的時(shí)候被阻塞了,執(zhí)行了 3s
  • 第四次執(zhí)行: 在 16s 開始執(zhí)行第四次,假設(shè)執(zhí)行的時(shí)候沒有被阻塞
  • 第四次執(zhí)行: 在 20s 開始執(zhí)行第五次,假設(shè)執(zhí)行的時(shí)候沒有被阻塞

2.2 固定延時(shí)

固定延時(shí) 策略表示任務(wù)在當(dāng)前任務(wù)執(zhí)行完成之后,固定延時(shí)一段時(shí)間再執(zhí)行下一個(gè)任務(wù),下面是一個(gè)例子:假設(shè)我們?cè)O(shè)置了一個(gè)固定速率為 5 的任務(wù),從 0s 開始執(zhí)行,也就是說這個(gè)任務(wù) 5s 執(zhí)行一次:

  • 第一次執(zhí)行: 在 0s 開始執(zhí)行一次,假設(shè)執(zhí)行時(shí)間是 3s
  • 第二次執(zhí)行: 在 8s 開始執(zhí)行第二次,假設(shè)執(zhí)行的時(shí)候被阻塞了,執(zhí)行了 8s
  • 第三次執(zhí)行: 在 21s 開始執(zhí)行第三次,假設(shè)執(zhí)行的時(shí)候被阻塞了,執(zhí)行了 3s
  • 第四次執(zhí)行: 在 29 開始執(zhí)行第四次,假設(shè)執(zhí)行的時(shí)候沒有被阻塞
  • 第四次執(zhí)行: 在 34s 開始執(zhí)行第五次,假設(shè)執(zhí)行的時(shí)候沒有被阻塞

上面的例子中其實(shí)固定速率的執(zhí)行和 Timer 是一樣的,但是固定延時(shí)有點(diǎn)不一樣,不知道你有沒有發(fā)現(xiàn),固定延時(shí)下執(zhí)行的時(shí)候每一個(gè)任務(wù)和前一個(gè)任務(wù)的時(shí)間間隔一定是 任務(wù)執(zhí)行時(shí)間 + 延時(shí)時(shí)間,其實(shí)相比于 Timer,ScheduledThreadPoolExecutor 的固定延時(shí)看起來更像是 “正宗” 一點(diǎn)的固定延時(shí)

3. API 解釋

3.1 schedule

還是老規(guī)矩,先看下 ScheduledThreadPoolExecutor 的幾個(gè) API,看看用法是什么樣的,首先就是 schedule 方法,這個(gè)方法就是普通的延時(shí)方法,只執(zhí)行一次,非周期調(diào)度

public class Pra {

    public static void main(String[] args) {
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(16);
        Thread thread = new Thread(() -> {
            try {
                System.out.println("Thread-Current: " + Thread.currentThread().getName() + ", time = " + getTime());
                if (Math.random() < 0.5) {
                    System.out.println("sleep: 3s");
                    Thread.sleep(3000);
                } else {
                    System.out.println("sleep: 8s");
                    Thread.sleep(8000);
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread-executor-run");
        executor.schedule(thread, 0, TimeUnit.SECONDS);
    }

    private static String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        return sdf.format(new Date());
    }

}

執(zhí)行結(jié)果如下所示,延遲 0s 就開始執(zhí)行任務(wù)

ScheduledThreadPoolExecutor 也提供了一個(gè) callable 類型的任務(wù)的實(shí)現(xiàn),使用 Callable 的好處就是可以獲取任務(wù)的實(shí)現(xiàn)返回值,如下例子所示:

public class Pra {

    public static void main(String[] args) {
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(16);

        // 創(chuàng)建一個(gè) Callable 任務(wù)
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("Task is running on thread: " + Thread.currentThread().getName());
                return 1; // 返回結(jié)果
            }
        };

        // 調(diào)度 Callable 任務(wù),在 0 秒后執(zhí)行
        ScheduledFuture<Integer> future = executor.schedule(task, 0, TimeUnit.SECONDS);
        try {
            // 獲取任務(wù)的結(jié)果
            Integer result = future.get();
            System.out.println("Task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    private static String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        return sdf.format(new Date());
    }

}

輸出結(jié)果如下所示:

3.2 固定延時(shí) - scheduleWithFixedDelay

public class Pra {

    public static void main(String[] args) {
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(16);

        Thread thread = new Thread(() -> {
            try {
                System.out.println("Thread-Current: " + Thread.currentThread().getName() + ", time = " + getTime());
                if (Math.random() < 0.5) {
                    System.out.println("sleep: 3s");
                    Thread.sleep(3000);
                } else {
                    System.out.println("sleep: 8s");
                    Thread.sleep(8000);
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread-executor-run");

        executor.scheduleWithFixedDelay(thread, 0, 5, TimeUnit.SECONDS);
    }

    private static String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        return sdf.format(new Date());
    }

}

輸入如下所示:

來分析一下:

首先第一次任務(wù) 2024-11-24 19:19:36:698 啟動(dòng),然后執(zhí)行時(shí)間 3s

第二次任務(wù)在 2024-11-24 19:19:44:718 啟動(dòng),跟第一次任務(wù)相差 8s,延時(shí) = 5s + 3s = 8s

第三次任務(wù)在 2024-11-24 19:19:52:741 啟動(dòng),跟第二次任務(wù)相差 8s,延時(shí) = 5s + 3s = 8s

第四次任務(wù)在 2024-11-24 19:20:05:760 啟動(dòng),跟第三次任務(wù)相差 13s,延時(shí) = 5s + 8s = 13s

第五次任務(wù)在 2024-11-24 19:20:13:773 啟動(dòng),跟第四次任務(wù)相差 8s,延時(shí) = 5s + 3s = 8s

第六次任務(wù)在 2024-11-24 19:20:26:787 啟動(dòng),跟第五次任務(wù)相差 13s,延時(shí) = 5s + 8s = 13s

可以看到 scheduleWithFixedDelay 的延時(shí)是相對(duì)于當(dāng)前時(shí)間 + 延時(shí)時(shí)間的,跟 Timer 的固定延時(shí)任務(wù)有點(diǎn)不同

3.2 固定速率 - scheduleWithFixedDelay

public class Pra {

    public static void main(String[] args) {
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(16);

        Thread thread = new Thread(() -> {
            try {
                System.out.println("Thread-Current: " + Thread.currentThread().getName() + ", time = " + getTime());
                if (Math.random() < 0.5) {
                    System.out.println("sleep: 3s");
                    Thread.sleep(3000);
                } else {
                    System.out.println("sleep: 8s");
                    Thread.sleep(8000);
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread-executor-run");

        executor.scheduleAtFixedRate(thread, 0, 5, TimeUnit.SECONDS);
    }

    private static String getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        return sdf.format(new Date());
    }

}

輸出結(jié)果如下:

來分析下上面的執(zhí)行流程,需要注意的是,ScheduledThreadPoolExecutor 的固定速率任務(wù)會(huì)在當(dāng)前任務(wù)執(zhí)行完之后再添加下一次要執(zhí)行的任務(wù)

  • 首先第一次任務(wù) 2024-11-24 16:23:25:762 啟動(dòng),然后執(zhí)行時(shí)間 8s,執(zhí)行完之后會(huì)添加一個(gè) 2024-11-24 16:23:30 s 執(zhí)行的任務(wù),當(dāng)前時(shí)間 2024-11-24 16:23:33 s
  • 第二次任務(wù)在 2024-11-24 16:23:33:770 啟動(dòng),因?yàn)?2024-11-24 16:23:33:770 超過了 2024-11-24 16:23:30 s 這個(gè)時(shí)間點(diǎn), 所以立刻執(zhí)行,執(zhí)行時(shí)間 3s,執(zhí)行完之后往隊(duì)列里面添加一個(gè) 2024-11-24 16:23:35 s 執(zhí)行的任務(wù),當(dāng)前時(shí)間 2024-11-24 16:23:36 s
  • 第二次任務(wù)在 2024-11-24 16:23:36:784 啟動(dòng),因?yàn)?2024-11-24 16:23:36:784 超過了 2024-11-24 16:23:35 s 這個(gè)時(shí)間點(diǎn), 所以立刻執(zhí)行,執(zhí)行時(shí)間 3s,執(zhí)行完之后往隊(duì)列里面添加一個(gè) 2024-11-24 16:23:40 s 執(zhí)行的任務(wù),當(dāng)前時(shí)間 2024-11-24 16:23:39 s
  • 第四次任務(wù)在 2024-11-24 16:23:40:739 啟動(dòng),因?yàn)榈谌齻€(gè)任務(wù)執(zhí)行完之后時(shí)間是 2024-11-24 16:23:39 s,還沒有到第四個(gè)任務(wù)執(zhí)行的時(shí)間點(diǎn),這時(shí)候就等待,等到 2024-11-24 16:23:40:739,執(zhí)行時(shí)間 3s,執(zhí)行完之后往隊(duì)列里面添加一個(gè) 2024-11-24 16:23:45 s 執(zhí)行的任務(wù),執(zhí)行完的時(shí)間當(dāng)前是 2024-11-24 16:23:42 s
  • 第五次任務(wù)在 2024-11-24 16:23:45:751 啟動(dòng),因?yàn)榈谒膫€(gè)任務(wù)執(zhí)行完之后時(shí)間是 2024-11-24 16:23:42 s,還沒有到第五個(gè)任務(wù)執(zhí)行的時(shí)間點(diǎn),這時(shí)候就等待,等到 2024-11-24 16:23:45:751,執(zhí)行時(shí)間 8s,執(zhí)行完之后往隊(duì)列里面添加一個(gè) 2024-11-24 16:23:50 s 執(zhí)行的任務(wù),執(zhí)行完的時(shí)間當(dāng)前是 2024-11-24 16:23:53 s
  • 第六次任務(wù)在 2024-11-24 16:23:53:763 啟動(dòng),因?yàn)榈诹鶄€(gè)任務(wù)執(zhí)行時(shí)間是 2024-11-24 16:23:50 s,而執(zhí)行完第五個(gè)任務(wù)已經(jīng)是 2024-11-24 16:23:53 s了,超過任務(wù)的執(zhí)行時(shí)間,所以會(huì)立馬執(zhí)行,執(zhí)行時(shí)間 3s,執(zhí)行完后往隊(duì)列里面添加一個(gè) 2024-11-24 16:23:55 s 的任務(wù),當(dāng)前時(shí)間是 2024-11-24 16:23:56 s

其實(shí)上面的解釋中可以把后面的毫秒去掉,這樣比較方便理解

4. 小結(jié)

上面就是幾個(gè) API 了,其中固定速率的和 Timer 的實(shí)現(xiàn)方式有點(diǎn)不同,后續(xù)文章中,我會(huì)對(duì) ScheduledThreadPoolExecutor 的源碼進(jìn)行詳細(xì)的解析,當(dāng)然在解析 ScheduledThreadPoolExecutor 之前首先需要知道下線程池的工作原理和工作流程。

以上就是一文帶你學(xué)會(huì)Java中ScheduledThreadPoolExecutor使用的詳細(xì)內(nèi)容,更多關(guān)于Java ScheduledThreadPoolExecutor的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringMVC實(shí)現(xiàn)賬號(hào)只能在一處登陸

    SpringMVC實(shí)現(xiàn)賬號(hào)只能在一處登陸

    這篇文章主要為大家詳細(xì)介紹了SpringMVC如何實(shí)現(xiàn)賬號(hào)只能在一處登陸,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 基于hibernate實(shí)現(xiàn)的分頁技術(shù)實(shí)例分析

    基于hibernate實(shí)現(xiàn)的分頁技術(shù)實(shí)例分析

    這篇文章主要介紹了基于hibernate實(shí)現(xiàn)的分頁技術(shù),結(jié)合實(shí)例形式分析了Hibernate分頁技術(shù)的原理,實(shí)現(xiàn)步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-03-03
  • javac -encoding 用法詳解

    javac -encoding 用法詳解

    當(dāng)我們編輯了一個(gè)Java源文件保存時(shí),是以操作系統(tǒng)默認(rèn)的字符編碼保存的(Windows xp默認(rèn)字符集是GBK)。這篇文章主要介紹了javac -encoding 用法詳解,非常具有實(shí)用價(jià)值。
    2016-12-12
  • Java21增強(qiáng)對(duì)Emoji表情符號(hào)處理示例詳解

    Java21增強(qiáng)對(duì)Emoji表情符號(hào)處理示例詳解

    這篇文章主要為大家介紹了Java21增強(qiáng)對(duì)Emoji表情符號(hào)處理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • 記一次集成swagger2(Knife4j)在線文檔提示:Knude4j文檔請(qǐng)求異常的解決辦法

    記一次集成swagger2(Knife4j)在線文檔提示:Knude4j文檔請(qǐng)求異常的解決辦法

    Knife4j是一個(gè)集Swagger2 和 OpenAPI3為一體的增強(qiáng)解決方案,下面這篇文章主要給大家介紹了關(guān)于一次集成swagger2(Knife4j)在線文檔提示:Knude4j文檔請(qǐng)求異常的解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Java之CMS和G1垃圾回收過程的異同說明

    Java之CMS和G1垃圾回收過程的異同說明

    CMS垃圾回收器主要基于并發(fā)-清理算法,目的是減少停頓時(shí)間,通過四個(gè)主要階段進(jìn)行垃圾回收:初始標(biāo)記、并發(fā)標(biāo)記、重新標(biāo)記和并發(fā)清理,G1垃圾回收器采用標(biāo)記-整理算法,是JDK9后的默認(rèn)垃圾收集器,設(shè)計(jì)為全功能全代收集器
    2024-09-09
  • Java實(shí)現(xiàn)批量查找與替換Excel文本的思路詳解

    Java實(shí)現(xiàn)批量查找與替換Excel文本的思路詳解

    在 Java 中,可以通過find和replace的方法來查找和替換單元格的數(shù)據(jù),下面小編將以Excel文件為例為大家介紹如何實(shí)現(xiàn)Excel文件內(nèi)容的批量替換,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • SpringBoot實(shí)現(xiàn)應(yīng)用開機(jī)自啟動(dòng)與進(jìn)程守護(hù)配置方案

    SpringBoot實(shí)現(xiàn)應(yīng)用開機(jī)自啟動(dòng)與進(jìn)程守護(hù)配置方案

    機(jī)房意外斷電,恢復(fù)供電后所有服務(wù)器重啟,但SpringBoot應(yīng)用沒有自動(dòng)啟動(dòng),事后排查發(fā)現(xiàn),沒有留下開機(jī)自啟動(dòng)配置文檔,所以本文整理了兩套SpringBoot應(yīng)用開機(jī)自啟動(dòng)與進(jìn)程守護(hù)方案,需要的朋友可以參考下
    2025-07-07
  • Idea跑的項(xiàng)目沒問題將程序install成jar包運(yùn)行報(bào)錯(cuò)空指針的問題

    Idea跑的項(xiàng)目沒問題將程序install成jar包運(yùn)行報(bào)錯(cuò)空指針的問題

    這篇文章主要介紹了Idea跑的項(xiàng)目沒問題,將程序install成jar包運(yùn)行報(bào)錯(cuò)空指針的問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • IDEA配置Maven的超詳細(xì)步驟

    IDEA配置Maven的超詳細(xì)步驟

    Maven是一個(gè)能使我們的java程序開發(fā)節(jié)省時(shí)間和精力,是開發(fā)變得相對(duì)簡(jiǎn)單,還能使開發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關(guān)于IDEA配置Maven的超詳細(xì)步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08

最新評(píng)論

临朐县| 肥城市| 大冶市| 沙坪坝区| 西和县| 绥滨县| 甘孜| 鹤壁市| 泸水县| 邳州市| 阳春市| 安陆市| 社会| 新邵县| 邵武市| 贵溪市| 革吉县| 大丰市| 蕉岭县| 滕州市| 达日县| 盐山县| 萍乡市| 平昌县| 日喀则市| 临江市| 屏南县| 蓝山县| 武邑县| 晋江市| 中牟县| 永年县| 中超| 寿阳县| 潜江市| 大悟县| 广宁县| 乌鲁木齐市| 拉孜县| 亚东县| 永川市|