成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

確保Spring Boot定時(shí)任務(wù)只執(zhí)行一次方案

開發(fā) 前端
雖然@Scheduled注解提供了一種直接的任務(wù)調(diào)度方式,但在靈活性方面做的不夠好。當(dāng)需要對(duì)任務(wù)規(guī)劃進(jìn)行更多控制(比如針對(duì)一次性執(zhí)行的任務(wù))時(shí),Spring的TaskScheduler接口提供了多功能的替代方案。

環(huán)境:Spring Boot3.2.5

1. 簡(jiǎn)介

在本篇文章中,我們將學(xué)習(xí)如何控制定時(shí)任務(wù)僅運(yùn)行一次。定時(shí)任務(wù)是自動(dòng)化諸如報(bào)告生成或發(fā)送通知等過程的常見做法。通常,我們?cè)O(shè)置這些任務(wù)定期運(yùn)行。然而,在某些情況下,我們可能希望一個(gè)任務(wù)在未來的某個(gè)時(shí)間點(diǎn)僅執(zhí)行一次,例如初始化資源或進(jìn)行數(shù)據(jù)遷移等操作。

接下來將探討在Spring Boot應(yīng)用中如何控制定時(shí)任務(wù)僅運(yùn)行一次的幾種方法。本文將通過帶有初始延遲的@Scheduled注解,到更靈活的方法,如TaskScheduler和自定義觸發(fā)器來避免任務(wù)的重復(fù)執(zhí)行。

2. 實(shí)戰(zhàn)案例

2.1 僅指定開始時(shí)間

雖然@Scheduled注解提供了一種直接的任務(wù)調(diào)度方式,但在靈活性方面做的不夠好。當(dāng)需要對(duì)任務(wù)規(guī)劃進(jìn)行更多控制(比如針對(duì)一次性執(zhí)行的任務(wù))時(shí),Spring的TaskScheduler接口提供了多功能的替代方案。使用TaskScheduler,我們可以以編程方式安排任務(wù),并指定任務(wù)的開始時(shí)間,從而為動(dòng)態(tài)調(diào)度場(chǎng)景提供了更大的靈活性。

TaskScheduler中最簡(jiǎn)單的方法允許我們定義一個(gè)Runnable任務(wù)和一個(gè)Instant,表示我們希望任務(wù)執(zhí)行的具體時(shí)間。這種方法使我們能夠動(dòng)態(tài)地安排任務(wù),而不必依賴于固定的注解,如下示例:

public class TaskComponent {
  private TaskScheduler taskScheduler = new SimpleAsyncTaskScheduler() ;
  public void schedule(Runnable task, Instant startTime) {
    taskScheduler.schedule(task, startTime) ;
  }
}

TaskScheduler中的所有其他方法都是用于周期性執(zhí)行的,因此這個(gè)方法對(duì)于一次性任務(wù)很有幫助。

注:這里我們使用了SimpleAsyncTaskScheduler,如果你的環(huán)境是Spring6.1以上版本,那么你還可以通過設(shè)置為虛擬線程執(zhí)行任務(wù)。

SimpleAsyncTaskScheduler scheduler = new SimpleAsyncTaskScheduler();
scheduler.setVirtualThreads(true) ;

接下來,我們可以通過如下方式測(cè)試該種方式的定時(shí)任務(wù)執(zhí)行

@Test
public void testOnceTask() {
  CountDownLatch cdl = new CountDownLatch(1) ;


  scheduler.schedule(() -> {
    cdl.countDown();
    // TODO, 任務(wù)Action
  }, Instant.now().plus(Duration.ofSeconds(1))) ;
  latch.await() ;
}

這里僅僅是因?yàn)橥ㄟ^單元測(cè)試時(shí)需要通過CountDownLatch進(jìn)行協(xié)助測(cè)試。生產(chǎn)環(huán)境無需這樣。

2.2 通過@Scheduled方式

我們還可以使用@Scheduled注解并設(shè)置初始延遲時(shí)間,同時(shí)不要設(shè)置fixedDelay或fixedRate屬性,如下示例:

@Component
public class TaskComponent {
  @Scheduled(initialDelay = 3000)
  public void task() {
    // TODO, 任務(wù)Action
  }
}

該方法在指定的初始化3s后執(zhí)行任務(wù)之后不會(huì)重復(fù)執(zhí)行。

2.3 自定義觸發(fā)器

我們還可以通過實(shí)現(xiàn)PeriodicTrigger,使用PeriodicTrigger我們可以進(jìn)行更多的控制任務(wù)執(zhí)行。通過重寫nextExecution()方法,以便僅在我們尚未觸發(fā)的情況下返回下一個(gè)執(zhí)行時(shí)間,如下示例:

public class PackTrigger extends PeriodicTrigger {
  public PackTrigger(Instant when) {
    super(Duration.ofSeconds(1)) ;
    Duration difference = Duration.between(Instant.now(), when) ;
    setInitialDelay(difference) ;
  }
  
  @Override
  public Instant nextExecution(TriggerContext triggerContext) {
    if (triggerContext.lastCompletion() == null) {
      return super.nextExecution(triggerContext) ;
    }
    // 返回null后將不會(huì)再執(zhí)行
    return null;
  }
}

由于我們只希望它執(zhí)行一次,因此可以將周期設(shè)置為任意值。最終,需要為我們的初始延遲傳遞一個(gè)Duration,因此我們需要計(jì)算任務(wù)期望執(zhí)行時(shí)刻與當(dāng)前時(shí)間之間的差值。

重寫nextExecution方法,如果完成狀態(tài)為null,則表示它尚未觸發(fā),因此允許它調(diào)用默認(rèn)實(shí)現(xiàn)。否則,返回null,這將使此觸發(fā)器僅執(zhí)行一次,調(diào)用示例如下:

TaskScheduler taskScheduler = new SimpleAsyncTaskScheduler() ;
taskScheduler.schedule(() -> {
  System.out.printf("%s, 執(zhí)行任務(wù)%n", Thread.currentThread().getName()) ;
}, new PackTrigger(Instant.now().plusSeconds(2))) ;

通過此種自定義觸發(fā)器的方式更加的靈活控制定時(shí)任務(wù)的執(zhí)行,也是當(dāng)前最優(yōu)的選擇。

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

2024-10-15 16:41:35

2012-02-07 13:31:14

SpringJava

2022-01-04 11:15:02

Spring Boot任務(wù)阻塞

2025-01-08 09:55:37

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

2022-03-23 11:45:39

Quartz數(shù)據(jù)庫節(jié)點(diǎn)

2023-11-02 18:01:24

SpringMVC配置

2025-04-21 02:20:00

2021-11-22 12:35:40

Python命令定時(shí)任務(wù)

2024-01-31 08:38:57

Python定時(shí)任務(wù)函數(shù)

2021-09-26 09:17:01

Python命令定時(shí)任務(wù)

2025-02-24 16:00:00

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

2022-03-28 08:31:29

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

2009-10-28 10:05:29

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

2010-03-10 15:47:58

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

2024-09-18 13:57:15

2023-12-08 14:42:17

Python開發(fā)

2024-03-12 11:39:30

Python開發(fā)

2024-09-23 05:10:00

微服務(wù)CORSSpringBoot

2019-02-25 15:44:16

開源RabbitMQSpring Clou

2024-11-04 16:01:01

點(diǎn)贊
收藏

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

主站蜘蛛池模板: 男人天堂国产 | 国内自拍偷拍一区 | 精品一区二区免费视频 | 精品欧美二区 | 一级在线视频 | 91久久国产精品 | 伊人网站在线 | 亚洲一区视频在线 | 国产做a爱片久久毛片 | 国产伦精品一区二区三区照片91 | 国产亚洲高清视频 | 亚洲欧美激情国产综合久久久 | 成人精品在线观看 | 国产精品久久久久久中文字 | 黄色大片免费观看 | 日韩一区二区在线视频 | 亚洲狠狠丁香婷婷综合久久久 | www.嫩草| 欧美精品久久久久 | 日韩视频一区二区 | 精品国产一级 | 亚洲成av人影片在线观看 | 日本午夜在线视频 | 性色av一区二区三区 | 成人久久18免费网站 | av网站免费在线观看 | 国产精品污www一区二区三区 | 欧美视频 亚洲视频 | 欧美一级片在线观看 | 久久最新| 国产精品国产三级国产aⅴ无密码 | 91免费电影 | 欧州一区二区 | 久久国产视频网 | 国产激情毛片 | 国产亚洲精品精品国产亚洲综合 | 青青草这里只有精品 | 精品免费国产视频 | 欧美国产91 | 丁香婷婷久久久综合精品国产 | 久久亚洲国产 |