亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

@Scheduled定時器使用注意事項(xiàng)及說明

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

@Scheduled定時器使用注意事項(xiàng)

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

一般在程序中直接使用定時器,但是最好設(shè)置一下JVM的默認(rèn)時區(qū),因?yàn)镴VM默認(rèn)時區(qū)可能和本機(jī)時區(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 虛擬機(jī)中所有涉及日期和時間的操作所使用的時區(qū)。
    //在Java中,通過 TimeZone.setDefault() 方法可以實(shí)現(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());
    }


}

為了美觀性,每個定時都單獨(dú)放在一個類,類目以功能+Schedule結(jié)尾,該類加上@Component表示交給spring管理,定時器的表達(dá)式可以在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 {

    //定時器表達(dá)式配置在nacos中
    @Scheduled(cron = "${testSchedule.oneCron}")
    //單獨(dú)配置線程池
    @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ā)性和性能。這對于處理大量獨(dú)立的任務(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回收機(jī)制銷毀,可以考慮編寫線程池

線程池代碼

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

}

總結(jié)

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

相關(guān)文章

最新評論