您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Springboot實現集成定時器和多線程異步處理,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
springboot集成多線程異步,直接上配置:
/** * 線程池異步配置 */ @Configuration @EnableAsync public class ThreadExecutorConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 設置核心線程數 executor.setCorePoolSize(5); // 設置最大線程數 executor.setMaxPoolSize(7); // 設置隊列容量 executor.setQueueCapacity(20); // 設置線程活躍時間(秒) executor.setKeepAliveSeconds(60); // 設置默認線程名稱 executor.setThreadNamePrefix("PASCAL-"); // 設置拒絕策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任務結束后再關閉線程池 executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new MyAsyncUncaughtExceptionHandler(); } }
下面的是對多線程異步的時候報出的異常處理方法,可以自定義一個處理多線程異常類來實現自身的業務邏輯.
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 } }
啟動類上要記得添加異步和開啟定時器的標簽
@SpringBootApplication @EnableScheduling @Async public class MultithreadingApplication { public static void main(String[] args) { SpringApplication.run(MultithreadingApplication.class, args); } }
業務邏輯方法:
@Async @Scheduled(initialDelay=1000,fixedDelay = 5000) public void test(){ SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss"); try { logger.info("當前線程為:"+Thread.currentThread().getName()+",方法開始時間為:"+format.format(new Date())); Thread.sleep(10000); logger.info("當前線程為:"+Thread.currentThread().getName()+",方法結束時間為:"+format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } }
對于@Schedule注解的使用方法:
點進去可以看到有幾個可選參數:
fixedDelay:控制方法執行的間隔時間,是以上一次方法執行完開始算起,如上一次方法執行阻塞住了,那么直到上一次執行完,并間隔給定的時間后,執行下一次
fixedRate:是按照一定的速率執行,是從上一次方法執行開始的時間算起,如果上一次方法阻塞住了,下一次也是不會執行,但是在阻塞這段時間內累計應該執行的次數,當不再阻塞時,一下子把這些全部執行掉,而后再按照固定速率繼續執行。
initialDelay:如: @Scheduled(initialDelay = 10000,fixedRate = 15000
這個定時器就是在上一個的基礎上加了一個initialDelay = 10000 意思就是在容器啟動后,延遲10秒后再執行一次定時器,以后每15秒再執行一次該定時器.
cron表達式可以定制化執行任務,但是執行的方式是與fixedDelay相近的,也是會按照上一次方法結束時間開始算起。
這里可以根據自身的業務需求,看到底選擇哪一個更適合,這里cron表達式就不再多言,可以結合自身應用場景來定
這樣,需求就實現了
測試結果:
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 : 當前線程為:PASCAL-1,方法開始時間為:11:12:41 2020-07-07 11:12:46.448 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當前線程為:PASCAL-2,方法開始時間為:11:12:46 2020-07-07 11:12:51.450 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當前線程為:PASCAL-3,方法開始時間為:11:12:51 2020-07-07 11:12:51.453 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當前線程為:PASCAL-1,方法結束時間為:11:12:51 2020-07-07 11:12:56.449 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當前線程為:PASCAL-2,方法結束時間為:11:12:56 2020-07-07 11:12:56.450 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當前線程為:PASCAL-4,方法開始時間為:11:12:56 2020-07-07 11:13:01.450 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當前線程為:PASCAL-3,方法結束時間為:11:13:01 2020-07-07 11:13:01.452 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當前線程為:PASCAL-5,方法開始時間為:11:13:01 2020-07-07 11:13:06.451 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當前線程為:PASCAL-4,方法結束時間為:11:13:06 2020-07-07 11:13:06.453 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當前線程為:PASCAL-1,方法開始時間為:11:13:06 2020-07-07 11:13:11.453 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當前線程為:PASCAL-5,方法結束時間為:11:13:11 2020-07-07 11:13:11.455 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當前線程為:PASCAL-2,方法開始時間為:11:13:11 2020-07-07 11:13:16.453 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當前線程為:PASCAL-1,方法結束時間為:11:13:16 2020-07-07 11:13:16.455 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當前線程為:PASCAL-3,方法開始時間為:11:13:16 2020-07-07 11:13:21.456 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當前線程為:PASCAL-2,方法結束時間為:11:13:21 2020-07-07 11:13:21.457 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當前線程為:PASCAL-4,方法開始時間為:11:13:21 2020-07-07 11:13:26.456 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當前線程為:PASCAL-3,方法結束時間為:11:13:26 2020-07-07 11:13:26.457 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當前線程為:PASCAL-5,方法開始時間為:11:13:26 2020-07-07 11:13:31.458 INFO 32360 --- [ PASCAL-4] c.e.multithreading.service.TestService : 當前線程為:PASCAL-4,方法結束時間為:11:13:31 2020-07-07 11:13:31.459 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當前線程為:PASCAL-1,方法開始時間為:11:13:31 2020-07-07 11:13:36.458 INFO 32360 --- [ PASCAL-5] c.e.multithreading.service.TestService : 當前線程為:PASCAL-5,方法結束時間為:11:13:36 2020-07-07 11:13:36.460 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當前線程為:PASCAL-2,方法開始時間為:11:13:36 2020-07-07 11:13:41.459 INFO 32360 --- [ PASCAL-1] c.e.multithreading.service.TestService : 當前線程為:PASCAL-1,方法結束時間為:11:13:41 2020-07-07 11:13:41.462 INFO 32360 --- [ PASCAL-3] c.e.multithreading.service.TestService : 當前線程為:PASCAL-3,方法開始時間為:11:13:41 2020-07-07 11:13:46.461 INFO 32360 --- [ PASCAL-2] c.e.multithreading.service.TestService : 當前線程為:PASCAL-2,方法結束時間為:11:13:46
每隔五秒執行一次
-----------------------分割線-----------------------
如果有多個定時任務,每個任務需要在不同的線程間處理的話,就要用另外的配置:如下:
/** * 配置多個schedule的線程配置 */ @Configuration @EnableScheduling public class ScheduleConfig implements SchedulingConfigurer{ /* * 并行任務 */ 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); } }
業務如下:
@Scheduled(cron = "*/5 * * * * ?") public void test1(){ SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss"); try { logger.info("當前線程為:"+Thread.currentThread().getName()+",方法開始時間為:"+format.format(new Date())); Thread.sleep(10000); logger.info("當前線程為:"+Thread.currentThread().getName()+",方法結束時間為:"+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("當前線程為:"+Thread.currentThread().getName()+",方法開始時間為:"+format.format(new Date())); Thread.sleep(10000); logger.info("當前線程為:"+Thread.currentThread().getName()+",方法結束時間為:"+format.format(new Date())); } catch (InterruptedException e) { e.printStackTrace(); } }
測試結果:
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 : 當前線程為:Schedule-Task-2,方法開始時間為:11:34:55 2020-07-07 11:34:55.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法開始時間為:11:34:55 2020-07-07 11:35:05.003 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-2,方法結束時間為:11:35:05 2020-07-07 11:35:05.003 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法結束時間為:11:35:05 2020-07-07 11:35:10.001 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-2,方法開始時間為:11:35:10 2020-07-07 11:35:10.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法開始時間為:11:35:10 2020-07-07 11:35:20.001 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-2,方法結束時間為:11:35:20 2020-07-07 11:35:20.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法結束時間為:11:35:20 2020-07-07 11:35:25.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法開始時間為:11:35:25 2020-07-07 11:35:25.003 INFO 27440 --- [Schedule-Task-3] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-3,方法開始時間為:11:35:25 2020-07-07 11:35:35.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法結束時間為:11:35:35 2020-07-07 11:35:35.003 INFO 27440 --- [Schedule-Task-3] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-3,方法結束時間為:11:35:35 2020-07-07 11:35:40.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法開始時間為:11:35:40 2020-07-07 11:35:40.002 INFO 27440 --- [Schedule-Task-5] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-5,方法開始時間為:11:35:40 2020-07-07 11:35:50.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-1,方法結束時間為:11:35:50 2020-07-07 11:35:50.002 INFO 27440 --- [Schedule-Task-5] c.e.multithreading.service.TestService : 當前線程為:Schedule-Task-5,方法結束時間為:11:35:50
關于Springboot實現集成定時器和多線程異步處理就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。