国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot實(shí)現(xiàn)固定、動態(tài)定時任務(wù) | 三種實(shí)現(xiàn)方式

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot實(shí)現(xiàn)固定、動態(tài)定時任務(wù) | 三種實(shí)現(xiàn)方式。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言:

閱讀完本文:?????

  1. 知曉 SpringBoot 用注解如何實(shí)現(xiàn)定時任務(wù)
  2. 明白 SpringBoot 如何實(shí)現(xiàn)一個動態(tài)定時任務(wù) (與數(shù)據(jù)庫相關(guān)聯(lián)實(shí)現(xiàn))
  3. 理解 SpringBoot 實(shí)現(xiàn)設(shè)置時間執(zhí)行定時任務(wù) (使用 ThreadPoolTaskScheduler 實(shí)現(xiàn))

一、注解實(shí)現(xiàn)定時任務(wù)

用注解實(shí)現(xiàn)是真的簡單,只要會 cron 表達(dá)式就行。???♂?

第一步: 主啟動類上加上 @EnableScheduling 注解

@EnableScheduling
@SpringBootApplication
public class SpringBootScheduled {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootScheduled.class);
    }
}
復(fù)制代碼

第二步:寫一個類,注入到Spring,關(guān)鍵就是 @Scheduled 注解。 () 里就是 cron 表達(dá)式,用來說明這個方法的執(zhí)行周期的。 ??

/**
 * 定時任務(wù) 靜態(tài)定時任務(wù)
 *
 * 第一位,表示秒,取值0-59
 * 第二位,表示分,取值0-59
 * 第三位,表示小時,取值0-23
 * 第四位,日期天/日,取值1-31
 * 第五位,日期月份,取值1-12
 * 第六位,星期,取值1-7,1表示星期天,2表示星期一
 * 第七位,年份,可以留空,取值1970-2099
 * @author crush
 * @since 1.0.0
 * @Date: 2021-07-27 21:13
 */
@Component
public class SchedulingTaskBasic {

    /**
     * 每五秒執(zhí)行一次
     */
    @Scheduled(cron = "*/5 * * * * ?")
    private void printNowDate() {
        long nowDateTime = System.currentTimeMillis();
        System.out.println("固定定時任務(wù)執(zhí)行:--->"+nowDateTime+",此任務(wù)為每五秒執(zhí)行一次");
    }
}
復(fù)制代碼

執(zhí)行效果:

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

源碼在文末。??

二、動態(tài)定時任務(wù)

其實(shí)也非常的簡單。

2.1、建數(shù)據(jù)表

第一步:建個數(shù)據(jù)庫表。

CREATE TABLE `tb_cron`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '動態(tài)定時任務(wù)時間表',
  `cron_expression` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '定時任務(wù)表達(dá)式',
  `cron_describe` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `tb_cron` VALUES (1, '0 0/1 * * * ?', '每分鐘執(zhí)行一次');
復(fù)制代碼

2.2、導(dǎo)入依賴,基礎(chǔ)編碼

第二步:導(dǎo)入數(shù)據(jù)庫相關(guān)依賴,做到能從數(shù)據(jù)庫查詢數(shù)據(jù)。大家都會。???♂?

第三步: 編碼

實(shí)體類:

@Data
@TableName("tb_cron")
public class Cron {
    private Long id;
    private String cronExpression;
    private String cronDescribe;
}
復(fù)制代碼

mapper層:

@Repository
public interface CronMapper extends BaseMapper<Cron> {
    @Select("select cron_expression from tb_cron where id=1")
    String getCron1();
}
復(fù)制代碼

2.3、主要實(shí)現(xiàn)代碼

第四步:寫一個類 實(shí)現(xiàn) SchedulingConfigurer??

實(shí)現(xiàn) void configureTasks(ScheduledTaskRegistrar taskRegistrar); 方法,此方法的作用就是根據(jù)給定的 ScheduledTaskRegistrar 注冊 TaskScheduler 和特定的Task實(shí)例

@Component
public class CompleteScheduleConfig implements SchedulingConfigurer {

    @Autowired
    @SuppressWarnings("all")
    CronMapper cronMapper;

    /**
     * 執(zhí)行定時任務(wù).
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
                //1.添加任務(wù)內(nèi)容(Runnable)
                () -> System.out.println("執(zhí)行動態(tài)定時任務(wù)1: " + LocalDateTime.now().toLocalTime()+",此任務(wù)執(zhí)行周期由數(shù)據(jù)庫中的cron表達(dá)式?jīng)Q定"),
                //2.設(shè)置執(zhí)行周期(Trigger)
                triggerContext -> {
                    //2.1 從數(shù)據(jù)庫獲取執(zhí)行周期
                    String cron = cronMapper.getCron1();
                    //2.2 合法性校驗(yàn).
                    if (cron!=null) {
                        // Omitted Code ..
                    }
                    //2.3 返回執(zhí)行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }
}
復(fù)制代碼

2.4、效果

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

注意:當(dāng)你修改了任務(wù)執(zhí)行周期后,生效時間為執(zhí)行完最近一次任務(wù)后。這一點(diǎn)是需要注意的,用生活中的例子理解就是我們?nèi)∠娫捒ǖ奶撞鸵惨聜€月生效,含義是一樣的。

源碼同樣在文末。

三、實(shí)現(xiàn)設(shè)置時間定時任務(wù)

通常業(yè)務(wù)場景是我前言中說的那樣,是一次性的定時任務(wù)。如:我設(shè)置了我寫的這篇文章的發(fā)布時間為今天下午的兩點(diǎn),執(zhí)行完就刪除沒有了。一次性的。

實(shí)現(xiàn)主要依靠于 TaskSchedulerScheduledFuture<?> schedule(Runnable task, Trigger trigger);方法來實(shí)現(xiàn)。其本質(zhì)和動態(tài)定時任務(wù)的實(shí)現(xiàn)是一樣的。

3.1、實(shí)現(xiàn)重點(diǎn)

代碼中都含有注解,不多做闡述。

import cn.hutool.core.convert.ConverterRegistry;
import com.crush.scheduled.entity.Task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;

/**
 * @author crush
 */
@Component
@Slf4j
public class DynamicTaskService {

    /**
     * 以下兩個都是線程安全的集合類。
     */
    public Map<String, ScheduledFuture<?>> taskMap = new ConcurrentHashMap<>();
    public List<String> taskList = new CopyOnWriteArrayList<String>();


    private final ThreadPoolTaskScheduler syncScheduler;

    public DynamicTaskService(ThreadPoolTaskScheduler syncScheduler) {
        this.syncScheduler = syncScheduler;
    }

    /**
     * 查看已開啟但還未執(zhí)行的動態(tài)任務(wù)
     * @return
     */
    public List<String> getTaskList() {
        return taskList;
    }


    /**
     * 添加一個動態(tài)任務(wù)
     *
     * @param task
     * @return
     */
    public boolean add(Task task) {
        // 此處的邏輯是 ,如果當(dāng)前已經(jīng)有這個名字的任務(wù)存在,先刪除之前的,再添加現(xiàn)在的。(即重復(fù)就覆蓋)
        if (null != taskMap.get(task.getName())) {
            stop(task.getName());
        }

        // hutool 工具包下的一個轉(zhuǎn)換類型工具類 好用的很
        ConverterRegistry converterRegistry = ConverterRegistry.getInstance();
        Date startTime = converterRegistry.convert(Date.class, task.getStart());

        // schedule :調(diào)度給定的Runnable ,在指定的執(zhí)行時間調(diào)用它。
        //一旦調(diào)度程序關(guān)閉或返回的ScheduledFuture被取消,執(zhí)行將結(jié)束。
        //參數(shù):
        //任務(wù) – 觸發(fā)器觸發(fā)時執(zhí)行的 Runnable
        //startTime – 任務(wù)所需的執(zhí)行時間(如果這是過去,則任務(wù)將立即執(zhí)行,即盡快執(zhí)行)
        ScheduledFuture<?> schedule = syncScheduler.schedule(getRunnable(task), startTime);
        taskMap.put(task.getName(), schedule);
        taskList.add(task.getName());
        return true;
    }


    /**
     * 運(yùn)行任務(wù)
     *
     * @param task
     * @return
     */
    public Runnable getRunnable(Task task) {
        return () -> {
            log.info("---動態(tài)定時任務(wù)運(yùn)行---");
            try {
                System.out.println("此時時間==>" + LocalDateTime.now());
                System.out.println("task中設(shè)定的時間==>" + task);
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("---end--------");
        };
    }

    /**
     * 停止任務(wù)
     *
     * @param name
     * @return
     */
    public boolean stop(String name) {
        if (null == taskMap.get(name)) {
            return false;
        }
        ScheduledFuture<?> scheduledFuture = taskMap.get(name);
        scheduledFuture.cancel(true);
        taskMap.remove(name);
        taskList.remove(name);
        return true;
    }
}
復(fù)制代碼

3.2、異步線程池的配置

/**
 * 異步線程池ThreadPoolExecutor 配置類
 *
 * @Author: crush
 * @Date: 2021-07-23 14:14
 */
@Configuration
public class ThreadPoolTaskExecutorConfig {

    @Bean
    public ThreadPoolTaskScheduler syncScheduler() {
        ThreadPoolTaskScheduler syncScheduler = new ThreadPoolTaskScheduler();
        syncScheduler.setPoolSize(5);
        // 這里給線程設(shè)置名字,主要是為了在項(xiàng)目能夠更快速的定位錯誤。
        syncScheduler.setThreadGroupName("syncTg");
        syncScheduler.setThreadNamePrefix("syncThread-");
        syncScheduler.initialize();
        return syncScheduler;
    }
}

復(fù)制代碼

3.3、業(yè)務(wù)代碼

這里需要注意一個點(diǎn),我給項(xiàng)目中的 LocalDateTime 做了類型轉(zhuǎn)換。這里沒貼出來(主要是復(fù)制以前的代碼遺留下來的,源碼中都有)

大家簡單使用,可以直接用注解 標(biāo)注在 LocalDateTime 屬性上即可。

package com.crush.scheduled.controller;
import com.crush.scheduled.entity.Task;
import com.crush.scheduled.service.DynamicTaskService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author: crush
 * @Date: 2021-07-29 15:26
 * version 1.0
 */
@RestController
@RequestMapping("/dynamicTask")
public class DynamicTaskController {

    private final DynamicTaskService dynamicTask;

    public DynamicTaskController(DynamicTaskService dynamicTask) {
        this.dynamicTask = dynamicTask;
    }

    /**
     * 查看已開啟但還未執(zhí)行的動態(tài)任務(wù)
     * @return
     */
    @GetMapping
    public List<String> getStartingDynamicTask(){
        return dynamicTask.getTaskList();
    }


    /**
     * 開啟一個動態(tài)任務(wù)
     * @param task
     * @return
     */
    @PostMapping("/dynamic")
    public String startDynamicTask(@RequestBody Task task){
        // 將這個添加到動態(tài)定時任務(wù)中去
        dynamicTask.add(task);
         return "動態(tài)任務(wù):"+task.getName()+" 已開啟";
    }


    /**
     *  根據(jù)名稱 停止一個動態(tài)任務(wù)
     * @param name
     * @return
     */
    @DeleteMapping("/{name}")
    public String stopDynamicTask(@PathVariable("name") String name){
        // 將這個添加到動態(tài)定時任務(wù)中去
        if(!dynamicTask.stop(name)){
            return "停止失敗,任務(wù)已在進(jìn)行中.";
        }
        return "任務(wù)已停止";
    }

}
復(fù)制代碼

簡單封裝的一個實(shí)體類:

/**
 * @Author: crush
 * @Date: 2021-07-29 15:35
 * version 1.0
 */
@Data
@Accessors(chain = true) // 方便鏈?zhǔn)骄帉?習(xí)慣所然 
public class Task {
    /**
     * 動態(tài)任務(wù)名曾
     */
    private String name;

    /**
     * 設(shè)定動態(tài)任務(wù)開始時間
     */
    private LocalDateTime start;
}
復(fù)制代碼

3.4、效果

????

開啟一個動態(tài)任務(wù):

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

查看開啟還未執(zhí)行的動態(tài)任務(wù):

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

執(zhí)行結(jié)果:

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

和我們代碼中是一模一樣的。

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

停止任務(wù):

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

spring定時任務(wù)動態(tài)配置,spring boot,java,mybatis

再去查看就是已經(jīng)停止的拉文章來源地址http://www.zghlxwxcb.cn/news/detail-598939.html

到了這里,關(guān)于SpringBoot實(shí)現(xiàn)固定、動態(tài)定時任務(wù) | 三種實(shí)現(xiàn)方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • SpringBoot開啟動態(tài)定時任務(wù)并手動、自動關(guān)閉

    場景需求:在執(zhí)行某個方法的兩小時之后進(jìn)行某個操作 涉及:定時任務(wù)、哈希表 需要注意: 業(yè)務(wù)邏輯層是單一實(shí)例的,所以在定時任務(wù)類內(nèi)操作業(yè)務(wù)邏輯層的某個屬性和在業(yè)務(wù)邏輯層內(nèi)操作的都是同一個。 使用Map存放數(shù)據(jù)不要用IdentityHashMap,因?yàn)镮dentityHashMap比較key值用的是

    2024年01月24日
    瀏覽(34)
  • SpringBoot 中實(shí)現(xiàn)定時任務(wù)的幾種方式

    SpringBoot 中實(shí)現(xiàn)定時任務(wù)的幾種方式

    定時任務(wù)在我們項(xiàng)目開發(fā)中也是很重要的,對于某些場景必須要用定時任務(wù) ,如定時發(fā)送郵件啊,定時統(tǒng)計(jì)數(shù)據(jù)等,這篇文章主要講講項(xiàng)目中實(shí)現(xiàn)定時任務(wù)的幾種方式。 這種方式很簡單,主要就是先@EnableScheduling開啟定時任務(wù)功能,然后在相應(yīng)的方法上添加@Scheduled()中間寫上

    2024年02月03日
    瀏覽(23)
  • SpringBoot第47講:SpringBoot定時任務(wù) - Netty HashedWheelTimer方式

    timer 和 ScheduledExecutorService 是JDK內(nèi)置的定時任務(wù)方案,而業(yè)內(nèi)還有一個經(jīng)典的定時任務(wù)的設(shè)計(jì)叫時間輪(Timing Wheel), Netty 內(nèi)部基于時間輪實(shí)現(xiàn)了一個 HashedWheelTimer 來 優(yōu)化百萬量級I/O超時的檢測 ,它是一個高性能,低消耗的數(shù)據(jù)結(jié)構(gòu),它適用于非準(zhǔn)實(shí)時,延遲的短平快任務(wù),例

    2024年02月09日
    瀏覽(21)
  • SpringBoot 動態(tài)操作定時任務(wù)(啟動、停止、修改執(zhí)行周期)增強(qiáng)版

    SpringBoot 動態(tài)操作定時任務(wù)(啟動、停止、修改執(zhí)行周期)增強(qiáng)版

    前段時間編寫了一篇博客 SpringBoot 動態(tài)操作定時任務(wù)(啟動、停止、修改執(zhí)行周期 ,該篇博客還是幫助了很多同學(xué)。 但是該篇博客中的方法有些不足的地方: 只能通過前端控制器controller手動注冊任務(wù)?!揪唧w的應(yīng)該是我們提前配置好我們的任務(wù),配置完成后讓springboot應(yīng)用

    2024年02月13日
    瀏覽(27)
  • Java -- 定時任務(wù)實(shí)現(xiàn)方式

    Java -- 定時任務(wù)實(shí)現(xiàn)方式

    在Java開發(fā)中,定時任務(wù)是一種十分常見的功能. 定時任務(wù)是在約定時間內(nèi)執(zhí)行的一段程序 如每天凌晨24點(diǎn)備份同步數(shù)據(jù),又或者電商平臺 30 分鐘后自動取消未支付的訂單,每隔一個小時拉取一次數(shù)據(jù)等都需要使用到定時器 批量處理數(shù)據(jù):批量統(tǒng)計(jì)上個月的某個數(shù)據(jù)。 時間驅(qū)

    2024年02月02日
    瀏覽(16)
  • Quartz實(shí)戰(zhàn):基于Quartz實(shí)現(xiàn)定時任務(wù)的動態(tài)調(diào)度,實(shí)現(xiàn)定時任務(wù)的增刪改查

    Quartz實(shí)戰(zhàn):基于Quartz實(shí)現(xiàn)定時任務(wù)的動態(tài)調(diào)度,實(shí)現(xiàn)定時任務(wù)的增刪改查

    Quartz使用文檔,使用Quartz實(shí)現(xiàn)動態(tài)任務(wù),Spring集成Quartz,Quartz集群部署,Quartz源碼分析 Quartz使用文檔,使用Quartz實(shí)現(xiàn)動態(tài)任務(wù),Spring集成Quartz,Quartz集群部署,Quartz源碼分析 此處省略了SysJob實(shí)體類,以及Mapper等對數(shù)據(jù)庫的操作。 本文只是大致實(shí)現(xiàn)一個基于Quartz實(shí)現(xiàn)定時任務(wù)

    2024年02月15日
    瀏覽(23)
  • springboot---定時任務(wù)實(shí)現(xiàn)

    springboot---定時任務(wù)實(shí)現(xiàn)

    任意類中創(chuàng)建一個方法,將該方法用@scheduled注解修飾,然后在項(xiàng)目的主方法上添加@EnableScheduling注解,定時任務(wù)就會生效。 但是需要注意的是定時任務(wù)不會一開始就執(zhí)行,會等待設(shè)定的時間 1.2.1. cron cron表達(dá)式是一個字符串,字符串以5或6個空格隔開,分開共6或7個域,每一個

    2024年02月11日
    瀏覽(20)
  • SpringBoot 實(shí)現(xiàn)定時任務(wù)

    SpringBoot 實(shí)現(xiàn)定時任務(wù)

    定時任務(wù)在實(shí)際項(xiàng)目開發(fā)中很常見,并且定時任務(wù)可以在各種場景中應(yīng)用,通過自動化操作和任務(wù)的規(guī)?;芾恚岣咝?、可靠性和工作質(zhì)量??梢詼p少手動操作,避免疏忽和錯誤,并節(jié)省時間和人力資源的投入 簡單易用: 使用注解驅(qū)動的方式,簡化了定時任務(wù)的配置和

    2024年02月12日
    瀏覽(32)
  • python實(shí)現(xiàn)定時任務(wù)的8種方式詳解

    python實(shí)現(xiàn)定時任務(wù)的8種方式詳解

    ????????在日常工作中,常常會用到需要周期性執(zhí)行的任務(wù),一種方式是采用 Linux 系統(tǒng)自帶的 crond 結(jié)合命令行實(shí)現(xiàn)。另外一種方式是直接使用Python。???????? ????????當(dāng)每隔一段時間就要執(zhí)行一段程序,或者往復(fù)循環(huán)執(zhí)行某一個任務(wù),這就需要使用定時任務(wù)來執(zhí)行

    2023年04月09日
    瀏覽(27)
  • linux下實(shí)現(xiàn)定時器的三種簡單方式

    linux下實(shí)現(xiàn)定時器的三種簡單方式

    目錄 一. sleep()和usleep() 1.sleep() 2.usleep() 3.毫秒級延時 二. signal與alarm() 三.?select 四.?一些總結(jié) ????????優(yōu)點(diǎn)是簡單便捷,直接調(diào)用即可,但是缺點(diǎn)也很明顯,精度不夠,特別是在系統(tǒng)負(fù)載比較大時,會發(fā)生超時現(xiàn)象。 1.sleep() #include unistd.h unsigned int sleep(unsigned int? ?secon

    2024年02月16日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包