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

速看!Spring Boot任務(wù)調(diào)度你不知道的使用技巧

開發(fā) 前端
我們可以通過實(shí)現(xiàn)SchedulingConfigurer接口來自定義相關(guān)任務(wù)調(diào)度的設(shè)置,這通常用于設(shè)置在執(zhí)行計(jì)劃任務(wù)時使用的特定TaskScheduler bean,或者以編程方式注冊計(jì)劃任務(wù)。

環(huán)境:SpringBoot3.2.5

1. TaskScheduler接口

Spring 提供了一個TaskSchedulerSPI,其中包含各種用于調(diào)度任務(wù)的方法,以便在未來某個時間點(diǎn)運(yùn)行。下面的列表顯示了 TaskScheduler 接口定義:

public interface TaskScheduler {
  ScheduledFuture schedule(Runnable task, Trigger trigger);
  ScheduledFuture scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);
  ScheduledFuture scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);
}

上面接口只列出了核心方法。

在SpringBoot環(huán)境中,我們可以直接注入該接口,如下示例:

@Resource
private TaskScheduler taskScheduler ;


@PostConstruct
public void initScheduler() {
  this.taskScheduler.schedule(() -> {
    System.out.println("執(zhí)行任務(wù)") ;
  }, new CronTrigger("*/2 * * * * *")) ;
}

上面通過cron表達(dá)式控制任務(wù)執(zhí)行周期。你也可以設(shè)置固定的執(zhí)行速率。

this.taskScheduler.scheduleAtFixedRate(() -> {
  System.out.println("固定周期指定任務(wù)") ;
}, Duration.ofSeconds(2)) ; // 每2s執(zhí)行

在默認(rèn)情況下SpringBoot創(chuàng)建的是ThreadPoolTaskScheduler

坑點(diǎn):默認(rèn)情況創(chuàng)建的ThreadPoolTaskScheduler只有一個線程,如果你當(dāng)前有多個定時任務(wù),如果出現(xiàn)重合那么任務(wù)會排隊(duì)執(zhí)行。通過如下參數(shù)修改線程池大小

spring:
  task:
    scheduling:
      thread-name-prefix: pack-task
      pool:
        size: 2

這里的spring.task.scheduling.pool.size默認(rèn)值為:1

2. 基于注解任務(wù)調(diào)用

基于注解方式實(shí)現(xiàn)任務(wù)的調(diào)用應(yīng)該是我們工作中應(yīng)用的主要方式,非常簡單方便,如下示例:

// 以固定的時間間隔執(zhí)行帶有注釋的方法,該時間間隔從上一次調(diào)用結(jié)束到下一次調(diào)用開始。
@Scheduled(fixedDelay = 2000)
public void fixedDelayTask() throws Exception {
  System.err.printf("Current Time: %s, Current Thread: %s%n", new SimpleDateFormat("HH:mm:ss").format(new Date()), Thread.currentThread().getName()) ;
  TimeUnit.SECONDS.sleep(1) ;
}

輸出結(jié)果

圖片

雖然間隔設(shè)置為2s,但是實(shí)際輸出是3s。

使用corn表達(dá)式

@Scheduled(cron = "*/3 * * * * *")
public void task1() {
  // TODO
}

每隔3s執(zhí)行

響應(yīng)式支持

從Spring Framework 6.1開始,幾種類型的反應(yīng)式方法也支持@Scheduled方法:

@Scheduled(fixedRate = 2, timeUnit = TimeUnit.SECONDS)
public Flux<Integer> reactiveTask() {
  return Flux.just(1, 2, 3).doOnNext(System.err::println) ;
}

在上面的示例中,會每隔2s打印1,2,3。

3. Cron表達(dá)式

一個格式良好的 cron 表達(dá)式(如 * * * * * *)由六個空格分隔的時間和日期字段組成,每個字段都有自己的有效值范圍:

圖片

特別說明:

  • 在范圍(或 *)后面加上 /,表示數(shù)字值在范圍內(nèi)的間隔
  • 用連字符 (-) 分隔的兩個數(shù)字表示一個數(shù)字范圍。指定的范圍是包含在內(nèi)的。如(10-15 * * * * *):每分鐘內(nèi)的10,11,12,13,14,15秒時都會運(yùn)行
  • 逗號 (,) 用于分隔列表中的項(xiàng)目;如(0 0 6,19 * * *)每天上午 6:00 和下午 7:00

寫cron表達(dá)式不太好理解。為了提高可讀性,Spring 支持以下表示常用序列的宏。因此,可以使用這些宏來代替六位數(shù)值:@Scheduled(cron = "@hourly")。

描述

@yearly (or @annually)

每年一次 (0 0 0 1 1 *)

@monthly

每月一次 (0 0 0 1 * *)

@weekly

每周一次 (0 0 0 * * 0)

@daily (or @midnight)

每天一次(0 0 0 * * *)

@hourly

每小時一次 (0 0 * * *)

如下示例:

@Scheduled(cron = "@hourly")
public void task2() {
  System.out.println("宏指令執(zhí)行任務(wù)") ;
}

這樣寫簡單多了。

4. 虛擬線程支持

從Spring6.1開始,支持虛擬線程(JDK21)執(zhí)行任務(wù)的調(diào)用。在SpringBoot環(huán)境下你需要開啟功能:

spring:
  threads:
    virtual:
      enabled: true

如下示例:

@Scheduled(cron = "*/3 * * * * *")
public void scheduler1() throws Exception {
  System.err.printf("當(dāng)前時間: %s, 當(dāng)前線程: %s, 是否虛擬線程: %b%n", new SimpleDateFormat("HH:mm:ss").format(new Date()), Thread.currentThread().getName(), Thread.currentThread().isVirtual()) ;
}

輸出結(jié)果

圖片圖片

如果使用了虛擬線程,那么下面的配置將沒有任何的意義。

spring:
  task:
    scheduling:
      pool:
        size: 10 #無意義

使用虛擬線程后,任務(wù)調(diào)用將使用單個調(diào)度線程,但每次執(zhí)行計(jì)劃任務(wù)時都會啟動一個新線程(虛擬線程)。

5. 自定義任務(wù)調(diào)度配置

我們可以通過實(shí)現(xiàn)SchedulingConfigurer接口來自定義相關(guān)任務(wù)調(diào)度的設(shè)置,這通常用于設(shè)置在執(zhí)行計(jì)劃任務(wù)時使用的特定TaskScheduler bean,或者以編程方式注冊計(jì)劃任務(wù)。如下示例:

@Component
public class PackSchedulingConfigurer implements SchedulingConfigurer {


  @Override
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler() ;
    taskScheduler.setThreadNamePrefix("my-task-") ;
    taskScheduler.afterPropertiesSet();
    taskRegistrar.setTaskScheduler(taskScheduler );
  }
}

上面的示例修改任務(wù)調(diào)度執(zhí)行的線程池對象。

public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  taskRegistrar.addCronTask(() -> {
    System.out.println("動態(tài)注冊調(diào)度任務(wù)...") ;
  }, "*/2 * * * * *");
}

上面示例,通過編程的方式動態(tài)注冊調(diào)度任務(wù)。

責(zé)任編輯:武曉燕 來源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2020-08-11 11:20:49

Linux命令使用技巧

2010-03-03 16:26:10

ubantu使用技巧

2019-07-23 15:56:56

Spring Boot部署servlet

2019-07-23 17:52:59

Spring BootJava開發(fā)

2017-03-02 14:05:42

AndroidAndroid Stu調(diào)試技巧

2023-12-21 14:40:09

Python編程語言

2015-08-13 09:03:14

調(diào)試技巧

2020-01-29 19:40:36

Python美好,一直在身邊Line

2021-01-05 11:22:58

Python字符串代碼

2022-12-07 08:16:50

Vue 3技巧數(shù)組

2009-04-14 21:38:05

LinuxUbuntu技巧

2020-02-21 14:55:02

Python代碼字符串

2021-01-28 10:04:40

JavaScript開發(fā)技術(shù)

2023-07-07 14:47:46

JavaScript技巧

2017-07-21 09:48:45

SQL索引查詢

2020-06-12 09:20:33

前端Blob字符串

2020-07-28 08:26:34

WebSocket瀏覽器

2022-07-17 06:53:24

微服務(wù)架構(gòu)

2011-09-15 10:25:40

windows7便箋

2017-10-10 13:58:38

前端CSS濾鏡技巧
點(diǎn)贊
收藏

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