Springboot集成定時(shí)器和多線程異步處理操作
需求:用@schedule標(biāo)簽進(jìn)行定時(shí)處理邏輯,由于業(yè)務(wù)處理速度慢,需要每次執(zhí)行邏輯放在不同的線程里異步執(zhí)行
springboot集成多線程異步,直接上配置:
/**
* 線程池異步配置
*/
@Configuration
@EnableAsync
public class ThreadExecutorConfig
implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 設(shè)置核心線程數(shù)
executor.setCorePoolSize(5);
// 設(shè)置最大線程數(shù)
executor.setMaxPoolSize(7);
// 設(shè)置隊(duì)列容量
executor.setQueueCapacity(20);
// 設(shè)置線程活躍時(shí)間(秒)
executor.setKeepAliveSeconds(60);
// 設(shè)置默認(rèn)線程名稱
executor.setThreadNamePrefix("PASCAL-");
// 設(shè)置拒絕策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任務(wù)結(jié)束后再關(guān)閉線程池
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncUncaughtExceptionHandler();
}
}
下面的是對多線程異步的時(shí)候報(bào)出的異常處理方法,可以自定義一個(gè)處理多線程異常類來實(shí)現(xiàn)自身的業(yè)務(wù)邏輯.
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import java.lang.reflect.Method;
public class MyAsyncUncaughtExceptionHandler implements
AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex,
Method method, Object... params) {
// handle exception
}
}
啟動類上要記得添加異步和開啟定時(shí)器的標(biāo)簽
@SpringBootApplication
@EnableScheduling
@Async
public class MultithreadingApplication {
public static void main(String[] args) {
SpringApplication.run(MultithreadingApplication.class, args);
}
}
業(yè)務(wù)邏輯方法:
@Async
@Scheduled(initialDelay=1000,fixedDelay = 5000)
public void test(){
SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss");
try {
logger.info("當(dāng)前線程為:"+Thread.currentThread().getName()+",方法開始時(shí)間為:"+format.format(new Date()));
Thread.sleep(10000);
logger.info("當(dāng)前線程為:"+Thread.currentThread().getName()+",方法結(jié)束時(shí)間為:"+format.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
對于@Schedule注解的使用方法:
點(diǎn)進(jìn)去可以看到有幾個(gè)可選參數(shù):
fixedDelay:控制方法執(zhí)行的間隔時(shí)間,是以上一次方法執(zhí)行完開始算起,如上一次方法執(zhí)行阻塞住了,那么直到上一次執(zhí)行完,并間隔給定的時(shí)間后,執(zhí)行下一次
fixedRate:是按照一定的速率執(zhí)行,是從上一次方法執(zhí)行開始的時(shí)間算起,如果上一次方法阻塞住了,下一次也是不會執(zhí)行,但是在阻塞這段時(shí)間內(nèi)累計(jì)應(yīng)該執(zhí)行的次數(shù),當(dāng)不再阻塞時(shí),一下子把這些全部執(zhí)行掉,而后再按照固定速率繼續(xù)執(zhí)行。
initialDelay:如: @Scheduled(initialDelay = 10000,fixedRate = 15000
這個(gè)定時(shí)器就是在上一個(gè)的基礎(chǔ)上加了一個(gè)initialDelay = 10000 意思就是在容器啟動后,延遲10秒后再執(zhí)行一次定時(shí)器,以后每15秒再執(zhí)行一次該定時(shí)器.
cron表達(dá)式可以定制化執(zhí)行任務(wù),但是執(zhí)行的方式是與fixedDelay相近的,也是會按照上一次方法結(jié)束時(shí)間開始算起。
這里可以根據(jù)自身的業(yè)務(wù)需求,看到底選擇哪一個(gè)更適合,這里cron表達(dá)式就不再多言,可以結(jié)合自身應(yīng)用場景來定
這樣,需求就實(shí)現(xiàn)了
測試結(jié)果:
20-07-07 11:12:40.436 INFO 32360 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path '' 2020-07-07 11:12:40.444 INFO 32360 --- [ main] c.e.m.MultithreadingApplication : Started MultithreadingApplication in 1.223 seconds (JVM running for 1.739) 2020-07-07 11:12:41.445 INFO 32360 --- [ scheduling-1] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 2020-07-07 11:12:41.452 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-1,方法開始時(shí)間為:11:12:41 2020-07-07 11:12:46.448 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-2,方法開始時(shí)間為:11:12:46 2020-07-07 11:12:51.450 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-3,方法開始時(shí)間為:11:12:51 2020-07-07 11:12:51.453 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-1,方法結(jié)束時(shí)間為:11:12:51 2020-07-07 11:12:56.449 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-2,方法結(jié)束時(shí)間為:11:12:56 2020-07-07 11:12:56.450 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-4,方法開始時(shí)間為:11:12:56 2020-07-07 11:13:01.450 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-3,方法結(jié)束時(shí)間為:11:13:01 2020-07-07 11:13:01.452 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-5,方法開始時(shí)間為:11:13:01 2020-07-07 11:13:06.451 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-4,方法結(jié)束時(shí)間為:11:13:06 2020-07-07 11:13:06.453 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-1,方法開始時(shí)間為:11:13:06 2020-07-07 11:13:11.453 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-5,方法結(jié)束時(shí)間為:11:13:11 2020-07-07 11:13:11.455 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-2,方法開始時(shí)間為:11:13:11 2020-07-07 11:13:16.453 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-1,方法結(jié)束時(shí)間為:11:13:16 2020-07-07 11:13:16.455 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-3,方法開始時(shí)間為:11:13:16 2020-07-07 11:13:21.456 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-2,方法結(jié)束時(shí)間為:11:13:21 2020-07-07 11:13:21.457 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-4,方法開始時(shí)間為:11:13:21 2020-07-07 11:13:26.456 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-3,方法結(jié)束時(shí)間為:11:13:26 2020-07-07 11:13:26.457 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-5,方法開始時(shí)間為:11:13:26 2020-07-07 11:13:31.458 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-4,方法結(jié)束時(shí)間為:11:13:31 2020-07-07 11:13:31.459 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-1,方法開始時(shí)間為:11:13:31 2020-07-07 11:13:36.458 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-5,方法結(jié)束時(shí)間為:11:13:36 2020-07-07 11:13:36.460 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-2,方法開始時(shí)間為:11:13:36 2020-07-07 11:13:41.459 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-1,方法結(jié)束時(shí)間為:11:13:41 2020-07-07 11:13:41.462 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-3,方法開始時(shí)間為:11:13:41 2020-07-07 11:13:46.461 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:PASCAL-2,方法結(jié)束時(shí)間為:11:13:46
每隔五秒執(zhí)行一次
-----------------------分割線-----------------------
如果有多個(gè)定時(shí)任務(wù),每個(gè)任務(wù)需要在不同的線程間處理的話,就要用另外的配置:如下:
/**
* 配置多個(gè)schedule的線程配置
*/
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer{
/*
* 并行任務(wù)
*/
public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
{
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setThreadNamePrefix("Schedule-Task-");
taskScheduler.setPoolSize(5);
taskScheduler.setAwaitTerminationSeconds(60);
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
taskScheduler.initialize();
taskRegistrar.setTaskScheduler(taskScheduler);
}
}
業(yè)務(wù)如下:
@Scheduled(cron = "*/5 * * * * ?")
public void test1(){
SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss");
try {
logger.info("當(dāng)前線程為:"+Thread.currentThread().getName()+",方法開始時(shí)間為:"+format.format(new Date()));
Thread.sleep(10000);
logger.info("當(dāng)前線程為:"+Thread.currentThread().getName()+",方法結(jié)束時(shí)間為:"+format.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Scheduled(cron = "*/5 * * * * ?")
public void test2(){
SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss");
try {
logger.info("當(dāng)前線程為:"+Thread.currentThread().getName()+",方法開始時(shí)間為:"+format.format(new Date()));
Thread.sleep(10000);
logger.info("當(dāng)前線程為:"+Thread.currentThread().getName()+",方法結(jié)束時(shí)間為:"+format.format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
測試結(jié)果:
2020-07-07 11:34:53.101 INFO 27440 --- [ main] c.e.m.MultithreadingApplication : Started MultithreadingApplication in 1.147 seconds (JVM running for 1.74) 2020-07-07 11:34:55.002 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-2,方法開始時(shí)間為:11:34:55 2020-07-07 11:34:55.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法開始時(shí)間為:11:34:55 2020-07-07 11:35:05.003 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-2,方法結(jié)束時(shí)間為:11:35:05 2020-07-07 11:35:05.003 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法結(jié)束時(shí)間為:11:35:05 2020-07-07 11:35:10.001 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-2,方法開始時(shí)間為:11:35:10 2020-07-07 11:35:10.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法開始時(shí)間為:11:35:10 2020-07-07 11:35:20.001 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-2,方法結(jié)束時(shí)間為:11:35:20 2020-07-07 11:35:20.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法結(jié)束時(shí)間為:11:35:20 2020-07-07 11:35:25.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法開始時(shí)間為:11:35:25 2020-07-07 11:35:25.003 INFO 27440 --- [Schedule-Task-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-3,方法開始時(shí)間為:11:35:25 2020-07-07 11:35:35.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法結(jié)束時(shí)間為:11:35:35 2020-07-07 11:35:35.003 INFO 27440 --- [Schedule-Task-3] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-3,方法結(jié)束時(shí)間為:11:35:35 2020-07-07 11:35:40.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法開始時(shí)間為:11:35:40 2020-07-07 11:35:40.002 INFO 27440 --- [Schedule-Task-5] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-5,方法開始時(shí)間為:11:35:40 2020-07-07 11:35:50.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-1,方法結(jié)束時(shí)間為:11:35:50 2020-07-07 11:35:50.002 INFO 27440 --- [Schedule-Task-5] c.e.multithreading.service.TestService : 當(dāng)前線程為:Schedule-Task-5,方法結(jié)束時(shí)間為:11:35:50
以上這篇Springboot集成定時(shí)器和多線程異步處理操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實(shí)現(xiàn)國際化i18n詳解
國際化(Internationalization,簡稱i18n)是指在軟件應(yīng)用中支持多種語言和文化的能力,本文將介紹如何在Spring?Boot應(yīng)用中實(shí)現(xiàn)國際化,需要的可以參考下2024-12-12
源碼解析springbatch的job運(yùn)行機(jī)制
這篇文章主要介紹了springbatch的job是如何運(yùn)行的,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
IDEA中Directory創(chuàng)建多級目錄的實(shí)現(xiàn)
本文主要介紹了IDEA中Directory創(chuàng)建多級目錄的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
Spring整合quartz做定時(shí)任務(wù)的示例代碼
這篇文章主要介紹了在spring項(xiàng)目使用quartz做定時(shí)任務(wù),首先我這里的項(xiàng)目已經(jīng)是一個(gè)可以跑起來的完整項(xiàng)目,web.xml里面的配置我就不貼出來了,具體實(shí)例代碼跟隨小編一起看看吧2022-01-01
Spring Cloud OAuth2中/oauth/token的返回內(nèi)容格式
Spring Cloud OAuth2 生成access token的請求/oauth/token的返回內(nèi)容就需要自定義,本文就詳細(xì)介紹一下,感興趣的可以了解一下2021-07-07
SpringBoot整合RabbitMQ實(shí)現(xiàn)RPC遠(yuǎn)程調(diào)用功能
在分布式系統(tǒng)中,RPC(Remote?Procedure?Call)是一種常用的通信機(jī)制,它可以讓不同的節(jié)點(diǎn)之間像調(diào)用本地函數(shù)一樣進(jìn)行函數(shù)調(diào)用,隱藏了底層的網(wǎng)絡(luò)通信細(xì)節(jié),通過本教程,你可以了解RPC的基本原理以及如何使用Java實(shí)現(xiàn)一個(gè)簡單的RPC客戶端和服務(wù)端2023-06-06
實(shí)例解析Java設(shè)計(jì)模式編程中的適配器模式使用
適配器模式的主要作用是在新接口和老接口之間進(jìn)行適配,通過將一個(gè)類的接口轉(zhuǎn)換成客戶期望的另一個(gè)接口,讓原本不兼容的接口可以合作無間,本文以實(shí)例解析Java設(shè)計(jì)模式編程中的適配器模式使用,需要的朋友可以參考下2016-05-05
Java Web實(shí)現(xiàn)登錄頁面驗(yàn)證碼驗(yàn)證功能
這篇文章主要介紹了Java Web登錄頁面驗(yàn)證碼驗(yàn)證功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12

