ScheduledThreadPoolExecutor 定時任務

来源:https://www.cnblogs.com/alex-oos/p/18080681
-Advertisement-
Play Games

目錄ScheduledThreadPoolExecutor一、概述二、常用方法1、schedule 方法2、scheduleAtFixedRate方法3.scheduleWithFixedDelay方法三、ScheduledExecutorService的創建方式 ScheduledThreadPo ...


目錄


ScheduledThreadPoolExecutor

一、概述

java 中ScheduledExecutorService介面是基於線程池設計的定時任務類,每個調度任務都會分配到線程池中的一個線程去執行,也就是說,任務是併發執行,互不影響。
其中的一個實現類是ScheduledThreadPoolExecutor

(1)>ScheduledThreadPoolExecutor實現ScheduledExecutorService介面,實現了一些定時任務處理的方法。

(2)>ScheduledThreadPoolExecutor繼承了ThreadPoolExecutor,可以通過線程池進行任務的管理和調度。

二、常用方法

1、schedule 方法

該方法的作用是提交一個延遲執行的任務,任務從提交時間算起延遲單位unit的deplay時間後執行,提交的不是周期任務,任務只會執行一次

ScheduledFuture<?> schedule(Runnable var1, long period, TimeUnit var4);
ScheduledFuture<V> schedule(Callable<V> var1, long var2, TimeUnit var4);

參數解析:

  • Runnable 需要運行的任務
  • period 間隔時間
  • unit參數是時間單元

代碼demo:

 ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
  System.out.println("當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// 使用的Runnable 匿名函數編寫的
service.schedule(() -> {
            System.out.println("我是使用schedule方法執行");
            Thread thread = Thread.currentThread();
            System.out.println("我是間隔1s執行的任務,線程名稱為:" + thread.getName() + ",線程ID為:" + thread.getId() + ",當前時間:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }, 1, TimeUnit.SECONDS);  // 延1秒後開始執行
 ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
 System.out.println("當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

service.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是使用schedule方法執行");
                Thread thread = Thread.currentThread();
                System.out.println("我是間隔1s執行的任務,線程名稱為:" + thread.getName() + ",線程ID為:" + thread.getId() + ",當前時間:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }, 1, TimeUnit.SECONDS);  // 延1秒後開始執行
ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
//使用 Callable 實現,該實現有返回值,可以接收返回的數據
ScheduledFuture<Object> future = service.schedule(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                System.out.println("我是使用schedule方法執行");
                Thread thread = Thread.currentThread();
                System.out.println("我是間隔1s執行的任務,線程名稱為:" + thread.getName() + ",線程ID為:" + thread.getId() + ",當前時間:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                return null;
            }
        }, 1, TimeUnit.SECONDS);// 延1秒後開始執行

        Object o = future.get();
        System.out.println(o);

輸出結果為:

當前時間為:2024-03-18 14:31:01
我是使用schedule方法執行
我是間隔1s執行的任務,線程名稱為:pool-1-thread-1,線程ID為:21,當前時間:2024-03-18 14:31:02

2、scheduleAtFixedRate方法

該方法相對起始時間點以固定頻率調用指定的任務(fixed-rate任務)。當把任務提交到線程池並延遲initialDelay時間後開始執行任務command。然後從initialDelay+period時間點再次執行,而後在initialDelay+2*period時間點再次執行,迴圈往複,直到拋出異常或者調用了任務的cancel方法取消了任務,或者關閉了線程池。

參數講解:

  • command 任務實例
  • initialDelay參數是初始化延遲時間
  • period參數是間隔時間
  • unit參數是時間單元
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

(1):當任務實例commod執行的時間小於延遲間隔時間delay情況


        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);

        System.out.println("當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("開始測試,當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("結束測試,當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }, 5, 5, TimeUnit.SECONDS); // 延遲5秒後執行,每隔3秒執行一次

執行結果為:

當前時間為:2024-03-18 15:15:06
開始測試,當前時間為:2024-03-18 15:15:11
結束測試,當前時間為:2024-03-18 15:15:14
 #第二次執行時間是第一次時間 + period 即11 + 5 = 16;
開始測試,當前時間為:2024-03-18 15:15:16
結束測試,當前時間為:2024-03-18 15:15:19

​ (2):當任務實例commod執行的時間大於間隔時間period情況

修改 TimeUnit.SECONDS.sleep(3); 為 TimeUnit.SECONDS.sleep(6);,執行查看運行結果!

執行結果為:

當前時間為:2024-03-18 15:19:57
開始測試,當前時間為:2024-03-18 15:20:02
結束測試,當前時間為:2024-03-18 15:20:08
開始測試,當前時間為:2024-03-18 15:20:09
結束測試,當前時間為:2024-03-18 15:20:15

總結
ScheduleAtFixedRate 每次執行時間為上一次任務開始起向後推一個時間間隔。分為兩種情況:
(1)若command執行的時間小於period若每次執行時間為 :initialDelay, initialDelay+period, initialDelay+2period, …;

(2)若command執行的時間大於period,則command執行完,下一次任務將立即執行!下即下一次任務不會按照預期的時間間隔執行,每次執行時間為 :initialDelay, initialDelay+taskExecutorTIme, initialDelay+2*taskExecutorTIme, …;

taskExecutorTIme為任務執行的時間!

3.scheduleWithFixedDelay方法

該方法的作用是,當任務執行完畢後,讓其延遲固定時間後再次運行(fixed-delay任務)。其中initialDelay表示提交任務後延遲多少時間開始執行任務command,delay表示當任務執行完畢後延長多少時間後再次運行command任務,unit是initialDelay和delay的時間單位。任務會一直重覆運行直到任務中拋出了異常,被取消了,或者關閉了線程池。

參數:

  • command參數是任務實例,
  • initialDelay參數是初始換延遲時間,
  • delay參數是延遲間隔時間,
  • unit參數是時間單元
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

(1):當任務實例commod執行的時間小於延遲間隔時間delay情況

 ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
        System.out.println("當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {

                System.out.println("開始測試,當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("結束測試,當前時間為:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }, 5, 3, TimeUnit.SECONDS); // 延遲5秒後執行,每隔3秒執行一次

執行結果:

當前時間為:2024-03-18 15:34:23
開始測試,當前時間為:2024-03-18 15:34:28
結束測試,當前時間為:2024-03-18 15:34:29
#第二次執行的時間 == 第一次任務開始時間+任務處理時間+delay延遲時間
#即 32 == 28 + 3秒 +  3秒 
開始測試,當前時間為:2024-03-18 15:34:32
結束測試,當前時間為:2024-03-18 15:34:33

(2):當任務實例commod執行的時間大於延遲間隔時間delay情況

修改 TimeUnit.SECONDS.sleep(3); 為 TimeUnit.SECONDS.sleep(6);,執行查看運行結果!

當前時間為:2024-03-18 15:38:28
開始測試,當前時間為:2024-03-18 15:38:33
結束測試,當前時間為:2024-03-18 15:38:39
#第二次任務執行開始時間 == 第一次任務執行開始時間 + 任務處理的時間 + delay延遲時間
#即 42 == 33 + 6 + 3
開始測試,當前時間為:2024-03-18 15:38:42
結束測試,當前時間為:2024-03-18 15:38:48

3:總結
不管任務command執行的時間是多長,下一次任務的執行時間都是上一次任務執行完後在等待延遲間隔delay時間後執行下一次任務。
ScheduleWithFixedDelay 每次執行時間為上一次任務結束起向後推一個時間間隔,即每次執行時間為:initialDelay, initialDelay+executeTime+delay, initialDelay+2executeTime+2delay

三、ScheduledExecutorService的創建方式

  public static void classCreate() {
        // 方式一
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
        // 方式二,方式二和方式一可以等價
        ScheduledExecutorService scheduledExecutorService1 = Executors.newScheduledThreadPool(1);

    }

參考地址:

https://www.cnblogs.com/xuwc/p/14053613.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄前言指令重排簡介指令重排對單例模式的影響改進方法std::call_once和std::once_flagstd::atomic和記憶體順序局部靜態變數總結參考文章 前言 在《單例模式學習》中曾提到懶漢式DCLP的單例模式實際也不是線程安全的,這是編譯器的指令重排導致的,本文就簡單討論一下指令重排 ...
  • python基礎學習 Created: November 28, 2023 6:48 PM Tags: Beginning 值得思考的一些事情 構建一項軟體設計有兩種方式:一種是將軟體設計得足夠簡單以至於明顯找不到缺陷;另一種是軟體設計得足夠複雜以至於找不到明顯的缺陷。 ——查爾斯·安東尼·理 ...
  • 虛函數表,以及虛函數指針是實現多態性(Polymorphism)的關鍵機制。多態性允許我們通過基類的指針或引用來調用派生類的函數 定義 虛函數(Virtual Function) 定義:類中使用virtual 關鍵字修飾的函數 叫做虛函數 語法: class Base { public: virtu ...
  • 拓展閱讀 junit5 系列教程 基於 junit5 實現 junitperf 源碼分析 Auto generate mock data for java test.(便於 Java 測試自動生成對象信息) Junit performance rely on junit5 and jdk8+.(ja ...
  • https://leetcode.cn/problems/h-index/description/?envType=study-plan-v2&envId=top-interview-150 註:題目有點難理解,多讀幾遍 可以這樣考慮,建立另一個臨時數組temp,當第i篇文章被引用citiation ...
  • Java 文件操作 文件處理簡介 文件處理是任何應用程式的重要部分。Java 提供了許多用於創建、讀取、更新和刪除文件的方法。 Java 文件處理 Java 中的文件處理主要通過 java.io 包中的 File 類完成。該類允許我們處理文件,包括創建、讀取、寫入和刪除文件。 創建 File 對象 ...
  • 在數據分析相關的工作中,Pandas無疑是一個強大的工具,它的易用性和靈活性廣受青睞。然而,隨著數據量的不斷增長和計算需求的日益複雜,Pandas代碼的性能問題也逐漸浮出水面。如何讓Pandas代碼運行得更快、更高效,成為了每一個人使用者都需要面對的挑戰。 今天,本文就一個簡化版的實際分析案例,來一 ...
  • 我們可以在命令行中執行各種命令,比如,創建文件、查看文件夾下文件、調用第三方工具等等。如果想在 java 代碼中執行命令應該怎麼操作呢?我們有兩種方式可以實現。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...