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
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...