欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解讀@Scheduled任務(wù)調(diào)度/定時(shí)任務(wù)非分布式

 更新時(shí)間:2024年08月05日 08:49:49   作者:霧林小妖  
這篇文章主要介紹了解讀@Scheduled任務(wù)調(diào)度/定時(shí)任務(wù)非分布式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1、功能概述

任務(wù)調(diào)度就是在規(guī)定的時(shí)間內(nèi)執(zhí)行的任務(wù)或者按照固定的頻率執(zhí)行的任務(wù)。是非常常見的功能之一。

常見的有JDK原生的Timer, ScheduledThreadPoolExecutor以及springboot提供的@Schduled。分布式調(diào)度框架如QuartZ、Elasticjob、XXL-JOB、SchedulerX、PowerJob等。

本文主要講解非分布式環(huán)境下的@Scheduled任務(wù)調(diào)度講解,以及@Scheduled結(jié)合多線程和@Async異步任務(wù)的使用。

當(dāng)然在任務(wù)不是很多的情況下@Scheduled也可以結(jié)合如Redis的鎖機(jī)制實(shí)現(xiàn)分布式的任務(wù)調(diào)度,但是還是建議在分布式環(huán)境下,使用分布式調(diào)度框架如:QuartZ、Elasticjob、XXL-JOB、SchedulerX、PowerJob等。

2、@Scheduled基本使用

2.1、創(chuàng)建springboot工程引入包信息

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.txc</groupId>
    <artifactId>scheduleddemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>scheduleddemo</name>
    <description>scheduleddemo</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
</project>

2.2、按照固定間隔執(zhí)行

  • fixedDelay:按照固定間隔執(zhí)行,上一個(gè)任務(wù)的結(jié)束到下一個(gè)任務(wù)的開始間隔。
  • initialDealay:延遲啟動(dòng),啟動(dòng)之后指定時(shí)間再執(zhí)行調(diào)度任務(wù)
  • @EnableScheduling:開啟任務(wù)調(diào)度,寫在類上只開啟當(dāng)前類中的任務(wù)調(diào)度,如果寫在啟動(dòng)類上則開啟項(xiàng)目中的所有任務(wù)調(diào)度。
@Slf4j
//加載類型開啟類中,加載啟動(dòng)類上,開啟整個(gè)項(xiàng)目
@EnableScheduling //是否開啟
@Component
public class MyScheduled {
    @Scheduled(fixedDelay = 3000,initialDelay = 3000)
    public void process(){
        log.info("=====process執(zhí)行========"+ LocalDateTime.now());
    }
}

結(jié)果分析:

從輸出結(jié)果中可以看出,程序每隔3s執(zhí)行一次

2.3、按照固定頻率執(zhí)行任務(wù)

說(shuō)明1fixedRate:按照固定頻率執(zhí)行任務(wù),如每三秒執(zhí)行一次,上一個(gè)任務(wù)下次任務(wù)的開始,由于此時(shí)是單線程,下一個(gè)任務(wù)開始需要等上一個(gè)任務(wù)結(jié)束。

說(shuō)明2:我們通過(guò)Thread.sleep(5000)設(shè)置任務(wù)執(zhí)行需要2s時(shí)間

@Slf4j
//加載類型開啟類中,加載啟動(dòng)類上,開啟整個(gè)項(xiàng)目
@EnableScheduling //是否開啟
@Component
public class MyScheduled {
@Scheduled(fixedRate = 3000,initialDelay = 3000)
public void process() throws InterruptedException {
log.info("=====process執(zhí)行fixedRate開始========"+ LocalDateTime.now());
      Thread.sleep(2000);
      log.info("=====process執(zhí)行fixedRate結(jié)束========"+ LocalDateTime.now());
    }
}

結(jié)果分析:

從結(jié)果中可以看出由于設(shè)置process執(zhí)行的時(shí)間為2s鐘,process按照固定的頻率(3s)每3s執(zhí)行一次,第一次開始是22:19:22,第二次開始是22:19:25

2.4、按照固定頻率執(zhí)行任務(wù)

說(shuō)明1fixedRate:按照固定頻率執(zhí)行任務(wù),如每三秒執(zhí)行一次,上一個(gè)任務(wù)下次任務(wù)的開始,由于此時(shí)是單線程,下一個(gè)任務(wù)開始需要等上一個(gè)任務(wù)結(jié)束。

說(shuō)明2:我們通過(guò)Thread.sleep(5000)設(shè)置任務(wù)執(zhí)行需要5s時(shí)間

@Slf4j
//加載類型開啟類中,加載啟動(dòng)類上,開啟整個(gè)項(xiàng)目
@EnableScheduling //是否開啟
@Component
public class MyScheduled {
@Scheduled(fixedRate = 3000,initialDelay = 3000)
public void process() throws InterruptedException {
  log.info("=====process執(zhí)行fixedRate開始========"+ LocalDateTime.now());
      Thread.sleep(5000);
      log.info("=====process執(zhí)行fixedRate結(jié)束========"+ LocalDateTime.now());
    }
}

結(jié)果分析:

從結(jié)果可以看出:雖然設(shè)置固定的頻率是3s,但是由于在單線程情況下下次任務(wù)的開啟需要等待上一個(gè)任務(wù)的結(jié)束,第一次任務(wù)開始時(shí)間為22:17:43,第二次任務(wù)開啟時(shí)間為22:17:48中間間隔了5s鐘。

2.5、通過(guò)公式設(shè)置定時(shí)任務(wù)

cron:可以通過(guò)特性的公式設(shè)定定時(shí)任務(wù),任務(wù)生成網(wǎng)站https://cron.qqe2.com/

如:可以設(shè)置每周三下午五點(diǎn)執(zhí)行,每月的月尾執(zhí)行一次等。

如上圖生成的語(yǔ)法表示:每分鐘的前五秒執(zhí)行process

@Slf4j
//加載類型開啟類中,加載啟動(dòng)類上,開啟整個(gè)項(xiàng)目
@EnableScheduling //是否開啟
@Component
public class MyScheduled {
@Scheduled(cron ="0,1,2,3,4 * * * * ? ")
public void process() throws InterruptedException {
     log.info("=====process執(zhí)行fixedRate開始========"+ LocalDateTime.now());
     Thread.sleep(5000);
     log.info("=====process執(zhí)行fixedRate結(jié)束========"+ LocalDateTime.now());
 }
}

結(jié)果分析:

從圖中可以看出每每分鐘開始的時(shí)候執(zhí)行,五秒后結(jié)束。

3、@Scheduled與多線程

加入多線程的目的是為了程序執(zhí)行的效率能夠提高。但是在設(shè)置多線程的時(shí)候,不能開辟過(guò)多的線程,因?yàn)榫€程資源非常的消耗cpu資源,必要的時(shí)候需要使用分布式任務(wù)調(diào)度。

3.1、非多線程的情況

理論上當(dāng)process1結(jié)束的時(shí)候,下次process1啟動(dòng)的時(shí)候需要等待process2執(zhí)行結(jié)束,否則1不能啟動(dòng),應(yīng)該這個(gè)時(shí)候依舊是單線程。

@Slf4j
//加載類型開啟類中,加載啟動(dòng)類上,開啟整個(gè)項(xiàng)目
@EnableScheduling //是否開啟
@Component
public class MyScheduled {
@Scheduled(fixedDelay = 3000)
public void process1() throws InterruptedException {
log.info("=====process1執(zhí)行開始========"+ LocalDateTime.now());
        Thread.sleep(5000);
        log.info("=====process1執(zhí)行結(jié)束========"+ LocalDateTime.now());
    }
@Scheduled(fixedDelay = 3000)
public void process2() throws InterruptedException {
       log.info("=====process2執(zhí)行開始========"+ LocalDateTime.now());
       Thread.sleep(5000);
       log.info("=====process2執(zhí)行結(jié)束========"+ LocalDateTime.now());
    }
}

結(jié)果分析:

從輸出結(jié)果可以看出process2的開始是等到process1結(jié)束后才執(zhí)行的。

3.2、多線程的情況

在啟動(dòng)類中定義線程池。值不需要設(shè)置太大,現(xiàn)成對(duì)cpu資源消耗大,搞不好容易讓系統(tǒng)宕機(jī)。

設(shè)置多線程后直接啟動(dòng)程序,繼續(xù)觀看process1和process2的輸出情況。

package com.txc.scheduleddemo;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 
@SpringBootApplication
public class ScheduleddemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(ScheduleddemoApplication.class, args);
    }
 
    @Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler();
        //設(shè)置線程池中線程的數(shù)量
        //多線程對(duì)cpu資源消耗較大,值不能太大。
        taskScheduler.setPoolSize(5);
        return taskScheduler;
    }
 
}

結(jié)果分析:

process1和process2使用的是不同的線程,一個(gè)線程為taskSheduler-1,一個(gè)線程為taskSheduler-2。

而且process1和process2是同時(shí)啟動(dòng)的,沒有出現(xiàn)相互等待的情況,因?yàn)楝F(xiàn)在使用的是多線程的情況。

4、@Scheduled與@ Async異步任務(wù)

在上面的案例中雖然process1和process2同時(shí)執(zhí)行了,沒有出現(xiàn)相互等待的情況。但是第二次process1和process2執(zhí)行依舊是等待程序5s結(jié)束后再等待3是執(zhí)行。

name如何能夠?qū)崿F(xiàn)即使process1執(zhí)行時(shí)間為5s,但是下一次process1的啟動(dòng)依舊是3s后。而不是當(dāng)前的8是后。這就可以使用異步任務(wù)@Async。當(dāng)然復(fù)雜的異步任務(wù)還是建議使用如MQ技術(shù)。

注意點(diǎn):@Async的使用需要寫在單獨(dú)的一個(gè)類中,不能與當(dāng)前調(diào)用業(yè)務(wù)寫在一起,否則不生效。

4.1、創(chuàng)建異步任務(wù)類及異步方法

@Component
public class AsyncTaskScheduled {
    @Async//那個(gè)方法需要使用異步調(diào)用,就使用該注解
    public void asyncMethod() {
        try{
            Thread.sleep(6000);//模擬異步執(zhí)行業(yè)務(wù)的時(shí)間
        }catch (Exception e){
            System.out.println(e.getStackTrace());
        }
    }
}

4.2、需要再啟動(dòng)類上開啟異步任務(wù)

@EnableAsync:開啟異步任務(wù)調(diào)度

@SpringBootApplication
@EnableAsync
public class ScheduleddemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(ScheduleddemoApplication.class, args);
    }
 
    @Bean
    public TaskScheduler taskScheduler(){
        ThreadPoolTaskScheduler taskScheduler=new ThreadPoolTaskScheduler();
        //設(shè)置線程池中線程的數(shù)量
        //多線程對(duì)cpu資源消耗較大,值不能太大。
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }
 
}

4.3、創(chuàng)建process3和process4方法

process3和process3與之前的process1和process2方法一樣都是基于多線程操作。

@Slf4j
//加載類型開啟類中,加載啟動(dòng)類上,開啟整個(gè)項(xiàng)目
@EnableScheduling //是否開啟
@Component
public class MyScheduled {
@Autowired
AsyncTaskScheduled asyncTaskScheduled;
@Scheduled(fixedDelay = 3000)
public void process3() throws InterruptedException {
log.info("=====process3執(zhí)行開始========"+ LocalDateTime.now());
        asyncTaskScheduled.asyncMethod();
        log.info("=====process3執(zhí)行結(jié)束========"+ LocalDateTime.now());
    }
@Scheduled(fixedDelay = 3000)
public void process4() throws InterruptedException {
        log.info("=====process4執(zhí)行開始========"+ LocalDateTime.now());
        asyncTaskScheduled.asyncMethod();
        log.info("=====process4執(zhí)行結(jié)束========"+ LocalDateTime.now());
    }
}

結(jié)果分析:

從結(jié)果可以看出,雖然異步任務(wù)執(zhí)行的時(shí)間為6s,但是process4第一次開始和第二次開始的時(shí)間間隔為3s.

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mybatis-plus?插入修改配置默認(rèn)值的實(shí)現(xiàn)方式

    mybatis-plus?插入修改配置默認(rèn)值的實(shí)現(xiàn)方式

    這篇文章主要介紹了mybatis-plus?插入修改配置默認(rèn)值的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Java overload和override的區(qū)別分析

    Java overload和override的區(qū)別分析

    方法的重寫(Overriding)和重載(Overloading)是Java多態(tài)性的不同表現(xiàn),想要了解更多請(qǐng)參考本文
    2012-11-11
  • PowerJob的OmsLogHandler工作流程源碼解析

    PowerJob的OmsLogHandler工作流程源碼解析

    這篇文章主要為大家介紹了PowerJob的OmsLogHandler工作流程源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Spring Boot和Hazelcast使用詳解

    Spring Boot和Hazelcast使用詳解

    這篇文章主要介紹了Spring Boot和Hazelcast使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • 利用SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式總結(jié)

    利用SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式總結(jié)

    關(guān)于動(dòng)態(tài)數(shù)據(jù)源的切換的方案有很多,核心只有兩種,一種是構(gòu)建多套環(huán)境,另一種是基于spring原生的AbstractRoutingDataSource切換,這篇文章主要給大家介紹了關(guān)于利用SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的兩種方式,需要的朋友可以參考下
    2021-10-10
  • Struts 2 實(shí)現(xiàn)Action的幾種方式

    Struts 2 實(shí)現(xiàn)Action的幾種方式

    本篇文章主要介紹了Struts 2 實(shí)現(xiàn)Action的幾種方式,Struts 2框架下實(shí)現(xiàn)Action類有三種方式,有興趣的可以了解一下
    2017-10-10
  • Netty4之如何實(shí)現(xiàn)HTTP請(qǐng)求、響應(yīng)

    Netty4之如何實(shí)現(xiàn)HTTP請(qǐng)求、響應(yīng)

    這篇文章主要介紹了Netty4之如何實(shí)現(xiàn)HTTP請(qǐng)求、響應(yīng)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 解決SpringBoot log4j日志沒生成的問題

    解決SpringBoot log4j日志沒生成的問題

    這篇文章主要介紹了解決SpringBoot log4j日志沒生成的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 內(nèi)存屏障由來(lái)及實(shí)現(xiàn)思路

    內(nèi)存屏障由來(lái)及實(shí)現(xiàn)思路

    這篇文章主要為大家詳細(xì)介紹了內(nèi)存屏障由來(lái)及實(shí)現(xiàn)思路的詳細(xì)講解,讓大家徹底的理解內(nèi)存屏障,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-01-01
  • java實(shí)現(xiàn)超市商品庫(kù)存管理平臺(tái)

    java實(shí)現(xiàn)超市商品庫(kù)存管理平臺(tái)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)超市商品庫(kù)存管理平臺(tái),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10

最新評(píng)論