自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

SpringBoot下使用定時(shí)任務(wù)的方式全揭秘

新聞 前端
定時(shí)任務(wù)作為一種系統(tǒng)調(diào)度工具,在一些需要有定時(shí)作業(yè)的系統(tǒng)中應(yīng)用廣泛,如每逢某個(gè)時(shí)間點(diǎn)統(tǒng)計(jì)數(shù)據(jù)、在將來某個(gè)時(shí)刻執(zhí)行某些動(dòng)作...

 

本文旨在用通俗的語言講述枯燥的知識(shí)

定時(shí)任務(wù)作為一種系統(tǒng)調(diào)度工具,在一些需要有定時(shí)作業(yè)的系統(tǒng)中應(yīng)用廣泛,如每逢某個(gè)時(shí)間點(diǎn)統(tǒng)計(jì)數(shù)據(jù)、在將來某個(gè)時(shí)刻執(zhí)行某些動(dòng)作...定時(shí)任務(wù)在主流開發(fā)語言均提供相應(yīng)的API供開發(fā)者調(diào)用,在Java中,實(shí)現(xiàn)定時(shí)任務(wù)有很多種方式,原生的方式實(shí)現(xiàn)一個(gè)完整定時(shí)任務(wù)需要由Timer、TimerTask兩個(gè)類,Timer是定時(shí)器類,用來按計(jì)劃開啟后臺(tái)線程執(zhí)行指定任務(wù),TimerTask一個(gè)抽象類,它的子類代表一個(gè)可以被Timer計(jì)劃的任務(wù)。除此之外,還可以用ScheduledExecutorService類或者使用第三方j(luò)ar庫Quartz,其中Quartz是一個(gè)優(yōu)秀的定時(shí)任務(wù)框架,發(fā)展至今已經(jīng)非常成熟,以致后來其他的定時(shí)任務(wù)框架的核心思想或底層大多源于Quartz。

springboot作為Java的一種開發(fā)框架,在springboot項(xiàng)目中實(shí)現(xiàn)定時(shí)任務(wù)不僅可以使用Java提供的原生方式,還可以使用springboot提供的定時(shí)任務(wù)API,下面,小編把Java原生和springboot所有的實(shí)現(xiàn)定時(shí)任務(wù)的方式做一個(gè)整合。

文章提綱:
1、使用線程
2、使用Timer類
3、使用ScheduledExecutorService類
4、使用Quartz
5、使用spring的@Scheduled注解
6、cron表達(dá)式

1. 線程實(shí)現(xiàn)

利用線程可以設(shè)定休眠時(shí)間的方式可以實(shí)現(xiàn)簡(jiǎn)單的定時(shí)任務(wù)邏輯。

  1. public static void main(String[] args){ 
  2.       //定時(shí)任務(wù)間隔時(shí)間 
  3.       int sleepTime=2*1000
  4.       new Thread(new Runnable() { 
  5.           @Override 
  6.           public void run() { 
  7.               while (true){ 
  8.                   try { 
  9.                       System.out.println("Thread方式執(zhí)行一次定時(shí)任務(wù)"); 
  10.                       //線程休眠規(guī)定時(shí)間 
  11.                       Thread.sleep(sleepTime); 
  12.                   } catch (InterruptedException e) { 
  13.                       e.printStackTrace(); 
  14.                   } 
  15.               } 
  16.           } 
  17.       }).start(); 
  18.   } 

2. Timer類

Timer類允許調(diào)度一個(gè)TimerTask任務(wù)。使用這種方式可以讓你的程序按照某一個(gè)頻度執(zhí)行。

  1. public static void main(String[] args){ 
  2.        int sleepTime=2*1000
  3.        TimerTask timerTask = new TimerTask() { 
  4.            @Override 
  5.            public void run() { 
  6.                System.out.println("Timer方式執(zhí)行一次定時(shí)任務(wù)"); 
  7.            } 
  8.        }; 
  9.        new Timer().schedule(timerTask,1,sleepTime); 
  10.    } 

3. ScheduledExecutorService類

ScheduledExecutorService,是基于線程池設(shè)計(jì)的定時(shí)任務(wù)類,每個(gè)調(diào)度任務(wù)都會(huì)分配到線程池中的一個(gè)線程去執(zhí)行,也就是說,任務(wù)是并發(fā)執(zhí)行,互不影響。
因此,基于ScheduledExecutorService類的定時(shí)任務(wù)類,歸根到底也是基于線程的調(diào)度實(shí)現(xiàn)的。

  1. public static void main(String[] args){ 
  2.      int sleepTime=2*1000
  3.      ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); 
  4.      scheduledExecutor.scheduleAtFixedRate( 
  5.              new Runnable() { 
  6.                  @Override 
  7.                  public void run() { 
  8.                      System.out.println("ScheduledExecutorService方式執(zhí)行一次定時(shí)任務(wù)"); 
  9.                  } 
  10.              } 
  11.      ,1,sleepTime, TimeUnit.SECONDS); 
  12.  } 

4. 整合Quartz

Quartz是一個(gè)完全由Java編寫的開源作業(yè)調(diào)度框架,為在 Java 應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡(jiǎn)單卻強(qiáng)大的機(jī)制,要理解它的使用方式,需要先理解它的幾個(gè)核心概念:

1)Job: 表示一個(gè)工作,要執(zhí)行的具體內(nèi)容。此接口中只有一個(gè)方法,如下:

  1. void execute(JobExecutionContext context) 

2)JobDetail: 表示一個(gè)具體的可執(zhí)行的調(diào)度程序,Job 是這個(gè)可執(zhí)行程調(diào)度程序所要執(zhí)行的內(nèi)容,另外 JobDetail 還包含了這個(gè)任務(wù)調(diào)度的方案和策略。

3)Trigger: 代表一個(gè)調(diào)度參數(shù)的配置,什么時(shí)候去調(diào)。

4)Scheduler: 代表一個(gè)調(diào)度容器,一個(gè)調(diào)度容器中可以注冊(cè)多個(gè) JobDetail 和Trigger。當(dāng) Trigger 與 JobDetail 組合,就可以被 Scheduler 容器調(diào)度了。

有了這些概念之后,我們就可以把Quartz整合到我們的springboot項(xiàng)目中了。

1. 引入quartz依賴

  1. <dependency> 
  2.    <groupId>org.springframework.boot</groupId> 
  3.    <artifactId>spring-boot-starter-quartz</artifactId> 
  4. </dependency> 

2.配置

  1. @Configuration 
  2. public class QuartzConfig { 
  3.     @Bean 
  4.     public JobDetail quartzDetail(){ 
  5.         return JobBuilder.newJob(QuartzTest.class).withIdentity("QuartzTest").storeDurably().build(); 
  6.     } 
  7.     @Bean 
  8.     public SimpleTrigger quartzTrigger(){ 
  9.         SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() 
  10.                 .withIntervalInSeconds(10
  11.                 .repeatForever(); 
  12.         return TriggerBuilder.newTrigger().forJob(quartzDetail()) 
  13.                 .withIdentity("QuartzTest"
  14.                 .withSchedule(scheduleBuilder) 
  15.                 .build(); 
  16.     } 

3. 測(cè)試

  1. public class QuartzTest extends QuartzJobBean { 
  2.     @Override 
  3.     protected void executeInternal(JobExecutionContext jobExecutionContext){ 
  4.         System.out.println("quartz執(zhí)行一次定時(shí)任務(wù) "); 
  5.     } 

5. 使用Scheduled注解

@Scheduled是spring為定時(shí)任務(wù)而生的一個(gè)注解,查看注解的源碼:

  1. @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. @Documented 
  4. @Repeatable(Schedules.class
  5. public @interface Scheduled { 
  6. //cron表達(dá)式 
  7.     String cron() default ""
  8. //接收一個(gè)java.util.TimeZone#ID。 
  9.     String zone() default ""
  10. //上一次執(zhí)行完畢時(shí)間點(diǎn)之后多長時(shí)間再執(zhí)行 
  11.     long fixedDelay() default -1
  12. //支持占位符形式的字符串類型的fixedDelay 
  13.     String fixedDelayString() default ""
  14. //上一次開始執(zhí)行時(shí)間點(diǎn)之后多長時(shí)間再執(zhí)行 
  15.     long fixedRate() default -1
  16. //支持占位符形式的字符串類型的fixedRateString 
  17.     String fixedRateString() default ""
  18. //頭一次延遲多長時(shí)間后再執(zhí)行     
  19.     long initialDelay() default -1
  20. //支持占位符形式的字符串類型的initialDelay 
  21.     String initialDelayString() default ""

可以看出:Scheduled注解中的參數(shù)用來設(shè)置“定時(shí)”動(dòng)作,通常情況下,比較常用的參數(shù)是cron(),這意味著我們需要學(xué)會(huì)一些cron表達(dá)式相關(guān)的語法,但由于內(nèi)容較多,篇幅較長,在這里暫不鋪開講解,我們把cron語法相關(guān)放到文章結(jié)尾,在此先講解如何用Scheduled注解來實(shí)現(xiàn)定時(shí)任務(wù)。

1)開啟定時(shí)任務(wù)支持

  1. @SpringBootApplication 
  2. /** 
  3.  * 開啟定時(shí)任務(wù)支持 
  4.  */ 
  5. @EnableScheduling 
  6. public class TestApplication  extends SpringBootServletInitializer { 
  7.     public static void main(String[] args) { 
  8.         SpringApplication.run(TestApplication.class, args); 
  9.     } 
  10.     @Override 
  11.     protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { 
  12.         return builder.sources(this.getClass()); 
  13.     } 

2)使用

  1. @Component 
  2. public class ScheduledTest { 
  3.     private Logger logger = LoggerFactory.getLogger(ScheduledTest.class); 
  4.     /** 
  5.      * 每15秒執(zhí)行一次定時(shí)任務(wù) 
  6.      */ 
  7.     @Scheduled(cron = "0/15 * * * * ? "
  8.     public void testCron(){ 
  9.         logger.info("Scheduled 執(zhí)行一次定時(shí)任務(wù)"); 
  10.     } 

6. cron表達(dá)式

cron表達(dá)式是一個(gè)字符串其語法為:

  1. [秒] [分] [小時(shí)] [日] [月] [周] [年] 

其中[年]為非必填項(xiàng),因此通常cron表達(dá)式通常由6或7部分內(nèi)容組成,內(nèi)容的取值為數(shù)字或者一些cron表達(dá)式約定的特殊字符,這些特殊字符稱為“通配符”,每一個(gè)通配符分別代指一種值。cron表達(dá)式可以用這樣的表格來表示:

順序 取值范圍 特殊字符串范圍
0~60 , - * /
0~60 , - * /
時(shí) 0-23 , - * /
1-31 , - * /
1-12 / JAN-DEC , - * ? / L W
1-7 / SUN-SAT , - * ? / L #
年(可省略) 1970-2099 , - * /

 

其中通配符的解釋以及作用如下:

通配符 代表的值 解釋
* 所有值 如:時(shí)字段為*,代表每小時(shí)都觸發(fā)
? 不指定值 如:周字段為?,代表表達(dá)式不關(guān)心是周幾
- 區(qū)間 如:時(shí)字段設(shè)置2-5,代表2,3,4,5點(diǎn)鐘時(shí)都觸發(fā)
, 多個(gè)值 如:時(shí)字段設(shè)置2,3,5,代表2,3,5點(diǎn)都會(huì)觸發(fā)
/ 遞增值 如:時(shí)字段設(shè)置0/2,代表每?jī)蓚€(gè)小時(shí)觸發(fā),時(shí)字段設(shè)置 2/5,代表從2時(shí)開始每隔5小時(shí)觸發(fā)一次
L 最后值 如:日字段設(shè)置L,代表本月最后一天
W 最近工作日 如:在日字段設(shè)置13W,代表沒約13日最近的那個(gè)工作日觸發(fā)一次
# 序號(hào) 如:在周字段設(shè)置5#2,代表每月的第二個(gè)周五

  1. 示例: 
  2. 2秒執(zhí)行一次:0/5 ? 
  3. 5分鐘執(zhí)行一次:0 0/5 * ? 
  4. 1分、12分、45分執(zhí)行一次:0 1,12,45 * ? 
  5. 每天23點(diǎn)5959秒執(zhí)行一次:59 59 23 ? 
  6. 每月15號(hào)凌晨3點(diǎn)執(zhí)行一次:0 0 3 15 * ? 
  7. 每月最后一天12點(diǎn)執(zhí)行一次:0 0 12 L *  

 

 

責(zé)任編輯:張燕妮 來源: segmentfault.com
相關(guān)推薦

2024-09-20 05:49:04

SpringBoot后端

2021-06-30 07:19:34

SpringBoot定時(shí)任務(wù)

2009-10-28 10:05:29

Ubuntucrontab定時(shí)任務(wù)

2022-08-15 15:43:29

Linuxcron

2024-10-15 16:41:35

2024-07-31 14:03:00

Spring定時(shí)任務(wù)管理

2010-03-10 15:47:58

crontab定時(shí)任務(wù)

2025-01-08 09:55:37

Spring接口數(shù)據(jù)庫

2017-08-16 16:41:04

JavaSpringBoot定時(shí)任務(wù)

2024-02-28 09:54:07

線程池配置

2009-06-22 13:30:00

定時(shí)任務(wù)Java

2025-02-24 16:00:00

SpringBoot定時(shí)任務(wù)開發(fā)

2024-05-13 09:49:30

.NETQuartz庫Cron表達(dá)式

2012-02-07 13:31:14

SpringJava

2023-01-04 09:23:58

2024-09-09 08:11:12

2021-08-05 07:28:25

Java實(shí)現(xiàn)方式

2023-12-19 08:09:06

Python定時(shí)任務(wù)Cron表達(dá)式

2022-03-28 08:31:29

線程池定時(shí)任務(wù)

2023-10-31 12:42:00

Spring動(dòng)態(tài)增刪啟停
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)