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

@Scheduled定時器使用注意事項及說明

 更新時間:2024年08月22日 10:25:57   作者:200.OK  
這篇文章主要介紹了@Scheduled定時器使用注意事項及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

@Scheduled定時器使用注意事項

首先定時器可以固定執(zhí)行時間使用cron表達式,也可以控制方法執(zhí)行的間隔時間fixedDelay,這里使用的是cron,創(chuàng)建了schedule包,將定時任務(wù)放在了schedule包下,下面開始進入正題。

一般在程序中直接使用定時器,但是最好設(shè)置一下JVM的默認(rèn)時區(qū),因為JVM默認(rèn)時區(qū)可能和本機時區(qū)不一樣,不同操作系統(tǒng)默認(rèn)時區(qū)可能不一樣。

使用靜態(tài)變量static聲明的靜態(tài)變量具有全局作用域,對全局造成影響,保證系統(tǒng)整個時區(qū)一致

如果只想針對某部分設(shè)置時區(qū)需要顯示指定時區(qū),不影響全局結(jié)果

package com.test.hello.task;

import com.test.hello.service.TestEntityService;
import com.test.hello.service.TestOneEntityService;
import com.test.hello.service.TestTwoEntityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

@Slf4j
@Component
public class TestTask {

    //全局修改時區(qū),設(shè)置JVM的默認(rèn)時區(qū),影響整個 Java 虛擬機中所有涉及日期和時間的操作所使用的時區(qū)。
    //在Java中,通過 TimeZone.setDefault() 方法可以實現(xiàn)對 JVM 默認(rèn)時區(qū)的修改。
    static {
        TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
    }

    //顯示指定時區(qū),不影響全局
    // 顯式指定使用的時區(qū)為 GMT+8
    ZoneId zoneId = ZoneId.of("GMT+8");

    // 獲取當(dāng)前時間
    LocalDateTime currentTime = LocalDateTime.now(zoneId);

    // 格式化日期時間
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String formattedTime = currentTime.format(formatter);



    @Autowired
    private TestEntityService testEntityService;

    @Autowired
    private TestOneEntityService testOneEntityService;

    @Autowired
    private TestTwoEntityService testTwoEntityService;


    /**
     * 每天的00:00:00執(zhí)行任務(wù)
     */
    @Scheduled(cron = "0 0 0 * * *")
    public void scheduled() {
        log.info("=====>>>>>使用cron  {}", testEntityService.countSum());
    }

    @Scheduled(cron = "0 0/1 * * * ?")
    public void scheduledStatisticsOnAboardNum() {
        log.info("=====>>>>>統(tǒng)計: 使用cron  {}", testEntityService.countSum());
        log.info("=====>>>>>)統(tǒng)計: 使用cron  {}", testOneEntityService.countSum());
        log.info("=====>>>>>合計統(tǒng)計: 使用cron  {}", testTwoEntityService.countSum());
    }


}

為了美觀性,每個定時都單獨放在一個類,類目以功能+Schedule結(jié)尾,該類加上@Component表示交給spring管理,定時器的表達式可以在nacos中聲明,防止后期需要改定時任務(wù)的時候頻繁修改代碼,只需要修改nacos配置文件即可(nacos配置文件中聲明定時器名字的時候不得以特殊字符開頭,不然會報錯踩坑)

package com.test.stats.schedule;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


@Component
@Slf4j
public class TestSchedule {

    //定時器表達式配置在nacos中
    @Scheduled(cron = "${testSchedule.oneCron}")
    //單獨配置線程池
    @Async("PoolThread")
    public void testScheduled() {
      //定時器執(zhí)行的邏輯代碼
    }
}

以上代碼使用到了 @Async異步注解,這里我使用了一個線程池,可以根據(jù)自己的業(yè)務(wù)需求自行決定。

定義線程池的意義在與所有執(zhí)行定時器都是副線程執(zhí)行,不影響主線程。

使用線程池的情況

  • 異步執(zhí)行任務(wù): 任務(wù)在后臺異步執(zhí)行,不阻塞當(dāng)前線程或應(yīng)用程序的其他部分時,使用線程池。例如,處理異步消息、發(fā)送電子郵件、執(zhí)行后臺計算等。
  • 提高并發(fā)性: 程序需要同時處理多個并發(fā)任務(wù)時,線程池可以有效地管理和分配系統(tǒng)資源,提高系統(tǒng)的并發(fā)性和性能。這對于處理大量獨立的任務(wù)或請求非常有用。
  • 避免線程創(chuàng)建和銷毀的開銷: 線程的創(chuàng)建和銷毀通常會帶來較大的開銷。通過使用線程池,可以避免頻繁地創(chuàng)建和銷毀線程,而是重用現(xiàn)有線程,減少資源開銷。
  • 限制資源使用: 使用線程池可以限制同時執(zhí)行的任務(wù)數(shù)量,以控制系統(tǒng)資源的使用。這對于避免系統(tǒng)過度負(fù)載或資源耗盡非常重要。
  • 任務(wù)隊列管理: 線程池通常具有任務(wù)隊列,可以將需要執(zhí)行的任務(wù)添加到隊列中。這使得任務(wù)按照預(yù)定的順序執(zhí)行,而無需手動管理線程的執(zhí)行。

總結(jié):

如果定時器執(zhí)行的比較頻繁,不想每次都new線程,而且內(nèi)次都從線程池里取線程,用完線程池自己根據(jù)GC回收機制銷毀,可以考慮編寫線程池

線程池代碼

package com.test.hello.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class ThreadPoolTaskConfig {


    //這里的命名可以在報錯的時候清楚是哪個線程報錯了
    @Bean("PoolThread")
    public ThreadPoolTaskExecutor threadPoolWorkTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //線程池創(chuàng)建的核心線程數(shù),線程池維護線程的最少數(shù)量,即使沒有任務(wù)需要執(zhí)行,也會一直存活
        executor.setCorePoolSize(8);
        //如果設(shè)置allowCoreThreadTimeout=true(默認(rèn)false)時,核心線程會超時關(guān)閉
        //executor.setAllowCoreThreadTimeOut(true);
        //阻塞隊列 當(dāng)核心線程數(shù)達到最大時,新任務(wù)會放在隊列中排隊等待執(zhí)行
        executor.setQueueCapacity(124);
        //最大線程池數(shù)量,當(dāng)線程數(shù)>=corePoolSize,且任務(wù)隊列已滿時。線程池會創(chuàng)建新線程來處理任
        //任務(wù)隊列已滿時, 且當(dāng)線程數(shù)=maxPoolSize,,線程池會拒絕處理任務(wù)而拋出異常
        executor.setMaxPoolSize(64);
        //當(dāng)線程空閑時間達到keepAliveTime時,線程會退出,直到線程數(shù)量=corePoolSize
        //允許線程空閑時間30秒,當(dāng)maxPoolSize的線程在空閑時間到達的時候銷毀
        //如果allowCoreThreadTimeout=true,則會直到線程數(shù)量=0
        executor.setKeepAliveSeconds(30);
        //spring 提供的 ThreadPoolTaskExecutor 線程池,是有setThreadNamePrefix() 方法的。
        //jdk 提供的ThreadPoolExecutor 線程池是沒有 setThreadNamePrefix() 方法的
        executor.setThreadNamePrefix("PoolThread");
        // rejection-policy:拒絕策略:當(dāng)線程數(shù)已經(jīng)達到maxSize的時候,如何處理新任務(wù)
        // CallerRunsPolicy():交由調(diào)用方線程運行,比如 main 線程;如果添加到線程池失敗,那么主線程會自己去執(zhí)行該任務(wù),不會等待線程池中的線程去執(zhí)行
        // AbortPolicy():該策略是線程池的默認(rèn)策略,如果線程池隊列滿了丟掉這個任務(wù)并且拋出RejectedExecutionException異常。
        // DiscardPolicy():如果線程池隊列滿了,會直接丟掉這個任務(wù)并且不會有任何異常
        // DiscardOldestPolicy():丟棄隊列中最老的任務(wù),隊列滿了,會將最早進入隊列的任務(wù)刪掉騰出空間,再嘗試加入隊列
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        executor.initialize();
        return executor;
    }

}

總結(jié)

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

相關(guān)文章

  • Spring+quartz實現(xiàn)定時發(fā)送郵件功能實例

    Spring+quartz實現(xiàn)定時發(fā)送郵件功能實例

    spring提供的定時發(fā)送郵件功能一直深受廣大web開發(fā)者的喜愛,這篇文章主要介紹了Spring+quartz實現(xiàn)定時發(fā)送郵件功能實例,有興趣的可以了解一下。
    2017-03-03
  • java Hibernate多對多映射詳解及實例代碼

    java Hibernate多對多映射詳解及實例代碼

    這篇文章主要介紹了java Hibernate多對多映射詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • JAVA中String類與StringBuffer類的區(qū)別

    JAVA中String類與StringBuffer類的區(qū)別

    這篇文章主要為大家詳細(xì)介紹了JAVA中String類與StringBuffer類的區(qū)別,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 基于Java編寫一個簡單的風(fēng)控組件

    基于Java編寫一個簡單的風(fēng)控組件

    這篇文章主要為大家詳細(xì)介紹了如何基于Java編寫一個簡單的風(fēng)控組件,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下
    2022-12-12
  • java實現(xiàn)XML與JSON轉(zhuǎn)換的便捷實用方法

    java實現(xiàn)XML與JSON轉(zhuǎn)換的便捷實用方法

    這篇文章主要為大家介紹了java實現(xiàn)XML與JSON轉(zhuǎn)換的便捷實用方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • 一文搞懂Java克隆及深拷貝與淺拷貝的區(qū)別

    一文搞懂Java克隆及深拷貝與淺拷貝的區(qū)別

    在編程中,通常通過實現(xiàn)Cloneable接口和重寫clone方法來實現(xiàn)對象的克隆,然而,需要注意的是克隆操作可能存在深拷貝和淺拷貝的區(qū)別,在使用時需要根據(jù)實際需求選擇合適的克隆方式,本文就給大家詳細(xì)講講什么是克隆以及深拷貝與淺拷貝的區(qū)別,需要的朋友可以參考下
    2023-08-08
  • 單一職責(zé)原則_動力節(jié)點Java學(xué)院整理

    單一職責(zé)原則_動力節(jié)點Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了單一職責(zé)原則的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java基礎(chǔ)之反射技術(shù)相關(guān)知識總結(jié)

    Java基礎(chǔ)之反射技術(shù)相關(guān)知識總結(jié)

    今天帶大家復(fù)習(xí)Java基礎(chǔ)知識,文中對Java反射技術(shù)介紹的非常詳細(xì),對正在學(xué)習(xí)Java的小伙伴們很有幫助,,需要的朋友可以參考下
    2021-05-05
  • 使用Idea簡單快速搭建springcloud項目的圖文教程

    使用Idea簡單快速搭建springcloud項目的圖文教程

    這篇文章主要介紹了使用Idea簡單快速搭建springcloud項目,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Springboot自動配置與@Configuration配置類詳解

    Springboot自動配置與@Configuration配置類詳解

    這篇文章主要介紹了SpringBoot中的@Configuration與自動配置,在進行項目編寫前,我們還需要知道一個東西,就是SpringBoot對我們的SpringMVC還做了哪些配置,包括如何擴展,如何定制,只有把這些都搞清楚了,我們在之后使用才會更加得心應(yīng)手
    2022-07-07

最新評論