Java使用線程池執(zhí)行定時(shí)任務(wù)
前言:
在 Java 語言中,有兩個(gè)線程池可以執(zhí)行定時(shí)任務(wù):ScheduledThreadPool 和 SingleThreadScheduledExecutor,其中 SingleThreadScheduledExecutor 可以看做是 ScheduledThreadPool 的單線程版本,它的用法和 ScheduledThreadPool 是一樣的,所以本文重點(diǎn)來看 ScheduledThreadPool 線程池的使用。
ScheduledThreadPool 執(zhí)行定時(shí)任務(wù)的方法有以下 3 個(gè):
- 使用 schedule 方法執(zhí)行定時(shí)任務(wù),只執(zhí)行一次定時(shí)任務(wù)。
- 使用 scheduleAtFixedRate 方法執(zhí)行定時(shí)任務(wù),執(zhí)行多次定時(shí)任務(wù)。
- 使用 scheduleWithFixedDelay 方法執(zhí)行定時(shí)任務(wù),執(zhí)行多次定時(shí)任務(wù)。
接下來我們看這 3 個(gè)方法的具體使用和區(qū)別。
1.schedule
schedule 方法只能執(zhí)行一次定時(shí)任務(wù),它需要傳遞 3 個(gè)參數(shù):
- 第 1 個(gè)參數(shù):傳遞一個(gè)任務(wù),Runnable 或 Callable 對(duì)象;
- 第 2 個(gè)參數(shù):添加定時(shí)任務(wù)后,再過多久開始執(zhí)行定時(shí)任務(wù);
- 第 3 個(gè)參數(shù):時(shí)間單位,配合參數(shù) 2 一起使用。
下面我們創(chuàng)建一個(gè) 3 秒以后執(zhí)行的定時(shí)任務(wù):
import java.time.LocalDateTime; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPoolExample { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建 ScheduledThreadPool 線程池 ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10); System.out.println("schedule 方法添加任務(wù):" + LocalDateTime.now()); threadPool.schedule(new Runnable() { @Override public void run() { System.out.println("執(zhí)行 schedule 方法:" + LocalDateTime.now()); } }, 3, TimeUnit.SECONDS); // 3s 之后執(zhí)行 // 以下代碼是給業(yè)務(wù)方法一個(gè)時(shí)間對(duì)照信息 TimeUnit.SECONDS.sleep(10); // 休眠 10s System.out.println("當(dāng)前時(shí)間:" + LocalDateTime.now()); } }
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果中可以看出,使用 schedule 方法只能執(zhí)行一次定時(shí)任務(wù)。
2.scheduleAtFixedRate
scheduleAtFixedRate 方法可以執(zhí)行多次定時(shí)任務(wù),此方法需要 4 個(gè)參數(shù):
- 第 1 個(gè)參數(shù):傳遞一個(gè)任務(wù),Runnable 或 Callable 對(duì)象;
- 第 2 個(gè)參數(shù):添加定時(shí)任務(wù)后,再過多久開始執(zhí)行定時(shí)任務(wù);
- 第 3 個(gè)參數(shù):定時(shí)任務(wù)執(zhí)行的時(shí)間間隔;
- 第 4 個(gè)參數(shù):時(shí)間單位,配合參數(shù) 2 和參數(shù) 3 一起使用。
下面我們創(chuàng)建一個(gè) 3 秒后執(zhí)行的定時(shí)任務(wù),每個(gè)定時(shí)任務(wù)執(zhí)行的時(shí)間間隔為 2 秒,
實(shí)現(xiàn)代碼如下:
import java.time.LocalDateTime; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPoolExample { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建 ScheduledThreadPool 線程池 ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10); System.out.println("scheduleAtFixedRate 方法添加任務(wù):" + LocalDateTime.now()); threadPool.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("執(zhí)行 scheduleAtFixedRate 方法:" + LocalDateTime.now()); // 休眠 2s try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } }, 3L, // 3s 后開始執(zhí)行定時(shí)任務(wù) 2L, // 定時(shí)任務(wù)的執(zhí)行間隔為 2s TimeUnit.SECONDS); // 描述上面兩個(gè)參數(shù)的時(shí)間單位 } }
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果可以看出,當(dāng)任務(wù)添加成功之后,3s 后開始執(zhí)行第一個(gè)定時(shí)任務(wù),之后每隔 2s 執(zhí)行一次定時(shí)任務(wù)。
3.scheduleWithFixedDelay
scheduleWithFixedDelay 方法的使用和 scheduleAtFixedRate 類似,但執(zhí)行效果完全不同,這個(gè)很容易理解如果效果一樣就不用創(chuàng)建兩個(gè)方法了。 scheduleWithFixedDelay 方法是在方法執(zhí)行完成之后,再隔 N 秒執(zhí)行下一個(gè)定時(shí)任務(wù),和 scheduleAtFixedRate 的固定時(shí)間執(zhí)行不同,scheduleWithFixedDelay 方法的執(zhí)行受定時(shí)任務(wù)執(zhí)行的時(shí)長影響,
比如以下代碼:
import java.time.LocalDateTime; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPoolExample { public static void main(String[] args) throws InterruptedException { // 創(chuàng)建 ScheduledThreadPool 線程池 ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(10); System.out.println("scheduleWithFixedDelay 方法添加任務(wù):" + LocalDateTime.now()); threadPool.scheduleWithFixedDelay(new Runnable() { @Override public void run() { System.out.println("執(zhí)行 scheduleWithFixedDelay 方法:" + LocalDateTime.now()); // 休眠 2s try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } }, 3L, // 3s 后開始執(zhí)行定時(shí)任務(wù) 2L, // 定時(shí)任務(wù)執(zhí)行完 2s 之后,再執(zhí)行下一個(gè)定時(shí)任務(wù) TimeUnit.SECONDS); // 描述上面兩個(gè)參數(shù)的時(shí)間單位 } }
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果可以看出,定時(shí)任務(wù)在 3s 之后開始執(zhí)行,以后每隔 4s 執(zhí)行一次,這 4s 包含了,定時(shí)任務(wù)執(zhí)行花費(fèi)的 2s,加上每隔 2s 執(zhí)行一次的時(shí)間間隔,也就是說 scheduleWithFixedDelay 是在任務(wù)執(zhí)行完 N 秒之后,再執(zhí)行下一次定時(shí)任務(wù)。
總結(jié)
線程池執(zhí)行定時(shí)任務(wù)的實(shí)現(xiàn)方法有 3 個(gè):
- 使用 schedule 方法執(zhí)行定時(shí)任務(wù),只執(zhí)行一次定時(shí)任務(wù)。
- 使用 scheduleAtFixedRate 方法執(zhí)行定時(shí)任務(wù),執(zhí)行多次定時(shí)任務(wù),它的執(zhí)行時(shí)間間隔是固定的,不受定時(shí)任務(wù)執(zhí)行時(shí)長影響(定時(shí)任務(wù)時(shí)間間隔 > 任務(wù)執(zhí)行時(shí)間)。
- 使用 scheduleWithFixedDelay 方法執(zhí)行定時(shí)任務(wù),執(zhí)行多次定時(shí)任務(wù),它是在定時(shí)任務(wù)執(zhí)行完之后,再隔 N 秒開始執(zhí)行下一次定時(shí)任務(wù),它的執(zhí)行時(shí)間受定時(shí)任務(wù)執(zhí)行時(shí)長影響。
到此這篇關(guān)于Java使用線程池執(zhí)行定時(shí)任務(wù)的文章就介紹到這了,更多相關(guān)Java行定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解SpringCloud Finchley Gateway 統(tǒng)一異常處理
這篇文章主要介紹了詳解SpringCloud Finchley Gateway 統(tǒng)一異常處理,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-10-10intellij IDEA配置springboot的圖文教程
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開發(fā)過程。接下來通過本文給大家介紹intellij IDEA配置springboot的圖文教程,感興趣的朋友一起看看吧2018-03-03聊聊@Autowired注解注入,寫接口名字還是實(shí)現(xiàn)類的名字
這篇文章主要介紹了聊聊@Autowired注解注入,寫接口名字還是實(shí)現(xiàn)類的名字,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringMVC之簡(jiǎn)單的增刪改查示例(SSM整合)
本篇文章主要介紹了SpringMVC之簡(jiǎn)單的增刪改查示例(SSM整合),這個(gè)例子是基于SpringMVC+Spring+Mybatis實(shí)現(xiàn)的。有興趣的可以了解一下。2017-03-03Springcloud Stream消息驅(qū)動(dòng)工具使用介紹
SpringCloud Stream由一個(gè)中間件中立的核組成,應(yīng)用通過SpringCloud Stream插入的input(相當(dāng)于消費(fèi)者consumer,它是從隊(duì)列中接收消息的)和output(相當(dāng)于生產(chǎn)者producer,它是發(fā)送消息到隊(duì)列中的)通道與外界交流2022-09-09SpringBoot自定義啟動(dòng)器Starter流程詳解
SpringBoot中的starter是一種非常重要的機(jī)制,能夠拋棄以前繁雜的配置,將其統(tǒng)一集成進(jìn)starter,應(yīng)用者只需要在maven中引入starter依賴,SpringBoot就能自動(dòng)掃描到要加載的信息并啟動(dòng)相應(yīng)的默認(rèn)配置。starter讓我們擺脫了各種依賴庫的處理,需要配置各種信息的困擾2022-11-11Java Date時(shí)間類型的操作實(shí)現(xiàn)
本文主要介紹Java Date 日期類型,以及Calendar的怎么獲取時(shí)間,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03