溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Springboot實(shí)現(xiàn)集成定時(shí)器和多線(xiàn)程異步處理

發(fā)布時(shí)間:2020-10-29 18:19:51 來(lái)源:億速云 閱讀:177 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)Springboot實(shí)現(xiàn)集成定時(shí)器和多線(xiàn)程異步處理,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

springboot集成多線(xiàn)程異步,直接上配置:

/**
 * 線(xiàn)程池異步配置
 */
 
@Configuration
@EnableAsync
public class ThreadExecutorConfig
    implements AsyncConfigurer { 
 
  @Override
  public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    // 設(shè)置核心線(xiàn)程數(shù)
    executor.setCorePoolSize(5);
    // 設(shè)置最大線(xiàn)程數(shù)
    executor.setMaxPoolSize(7);
    // 設(shè)置隊(duì)列容量
    executor.setQueueCapacity(20);
    // 設(shè)置線(xiàn)程活躍時(shí)間(秒)
    executor.setKeepAliveSeconds(60);
    // 設(shè)置默認(rèn)線(xiàn)程名稱(chēng)
    executor.setThreadNamePrefix("PASCAL-");
    // 設(shè)置拒絕策略
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    // 等待所有任務(wù)結(jié)束后再關(guān)閉線(xiàn)程池
    executor.setWaitForTasksToCompleteOnShutdown(true);
    executor.initialize();
    return executor;
  }
 
  @Override
  public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new MyAsyncUncaughtExceptionHandler();
  }
}

下面的是對(duì)多線(xiàn)程異步的時(shí)候報(bào)出的異常處理方法,可以自定義一個(gè)處理多線(xiàn)程異常類(lèi)來(lái)實(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
  }
}

啟動(dòng)類(lèi)上要記得添加異步和開(kāi)啟定時(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)前線(xiàn)程為:"+Thread.currentThread().getName()+",方法開(kāi)始時(shí)間為:"+format.format(new Date()));
      Thread.sleep(10000);
      logger.info("當(dāng)前線(xiàn)程為:"+Thread.currentThread().getName()+",方法結(jié)束時(shí)間為:"+format.format(new Date()));
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

對(duì)于@Schedule注解的使用方法:

點(diǎn)進(jìn)去可以看到有幾個(gè)可選參數(shù):

fixedDelay:控制方法執(zhí)行的間隔時(shí)間,是以上一次方法執(zhí)行完開(kāi)始算起,如上一次方法執(zhí)行阻塞住了,那么直到上一次執(zhí)行完,并間隔給定的時(shí)間后,執(zhí)行下一次

fixedRate:是按照一定的速率執(zhí)行,是從上一次方法執(zhí)行開(kāi)始的時(shí)間算起,如果上一次方法阻塞住了,下一次也是不會(huì)執(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 意思就是在容器啟動(dòng)后,延遲10秒后再執(zhí)行一次定時(shí)器,以后每15秒再執(zhí)行一次該定時(shí)器.

cron表達(dá)式可以定制化執(zhí)行任務(wù),但是執(zhí)行的方式是與fixedDelay相近的,也是會(huì)按照上一次方法結(jié)束時(shí)間開(kāi)始算起。

這里可以根據(jù)自身的業(yè)務(wù)需求,看到底選擇哪一個(gè)更適合,這里cron表達(dá)式就不再多言,可以結(jié)合自身應(yīng)用場(chǎng)景來(lái)定

這樣,需求就實(shí)現(xiàn)了

測(cè)試結(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)前線(xiàn)程為:PASCAL-1,方法開(kāi)始時(shí)間為:11:12:41
2020-07-07 11:12:46.448 INFO 32360 --- [    PASCAL-2] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:PASCAL-2,方法開(kāi)始時(shí)間為:11:12:46
2020-07-07 11:12:51.450 INFO 32360 --- [    PASCAL-3] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:PASCAL-3,方法開(kāi)始時(shí)間為:11:12:51
2020-07-07 11:12:51.453 INFO 32360 --- [    PASCAL-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-4,方法開(kāi)始時(shí)間為:11:12:56
2020-07-07 11:13:01.450 INFO 32360 --- [    PASCAL-3] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-5,方法開(kāi)始時(shí)間為:11:13:01
2020-07-07 11:13:06.451 INFO 32360 --- [    PASCAL-4] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-1,方法開(kāi)始時(shí)間為:11:13:06
2020-07-07 11:13:11.453 INFO 32360 --- [    PASCAL-5] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-2,方法開(kāi)始時(shí)間為:11:13:11
2020-07-07 11:13:16.453 INFO 32360 --- [    PASCAL-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-3,方法開(kāi)始時(shí)間為:11:13:16
2020-07-07 11:13:21.456 INFO 32360 --- [    PASCAL-2] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-4,方法開(kāi)始時(shí)間為:11:13:21
2020-07-07 11:13:26.456 INFO 32360 --- [    PASCAL-3] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-5,方法開(kāi)始時(shí)間為:11:13:26
2020-07-07 11:13:31.458 INFO 32360 --- [    PASCAL-4] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-1,方法開(kāi)始時(shí)間為:11:13:31
2020-07-07 11:13:36.458 INFO 32360 --- [    PASCAL-5] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-2,方法開(kāi)始時(shí)間為:11:13:36
2020-07-07 11:13:41.459 INFO 32360 --- [    PASCAL-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:PASCAL-3,方法開(kāi)始時(shí)間為:11:13:41
2020-07-07 11:13:46.461 INFO 32360 --- [    PASCAL-2] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:PASCAL-2,方法結(jié)束時(shí)間為:11:13:46

每隔五秒執(zhí)行一次

-----------------------分割線(xiàn)-----------------------

如果有多個(gè)定時(shí)任務(wù),每個(gè)任務(wù)需要在不同的線(xiàn)程間處理的話(huà),就要用另外的配置:如下:

/**
 * 配置多個(gè)schedule的線(xiàn)程配置
 */
@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)前線(xiàn)程為:"+Thread.currentThread().getName()+",方法開(kāi)始時(shí)間為:"+format.format(new Date()));
      Thread.sleep(10000);
      logger.info("當(dāng)前線(xiàn)程為:"+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)前線(xiàn)程為:"+Thread.currentThread().getName()+",方法開(kāi)始時(shí)間為:"+format.format(new Date()));
      Thread.sleep(10000);
      logger.info("當(dāng)前線(xiàn)程為:"+Thread.currentThread().getName()+",方法結(jié)束時(shí)間為:"+format.format(new Date()));
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

測(cè)試結(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)前線(xiàn)程為:Schedule-Task-2,方法開(kāi)始時(shí)間為:11:34:55
2020-07-07 11:34:55.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:Schedule-Task-1,方法開(kāi)始時(shí)間為:11:34:55
2020-07-07 11:35:05.003 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為: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)前線(xiàn)程為:Schedule-Task-2,方法開(kāi)始時(shí)間為:11:35:10
2020-07-07 11:35:10.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:Schedule-Task-1,方法開(kāi)始時(shí)間為:11:35:10
2020-07-07 11:35:20.001 INFO 27440 --- [Schedule-Task-2] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為: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)前線(xiàn)程為:Schedule-Task-1,方法開(kāi)始時(shí)間為:11:35:25
2020-07-07 11:35:25.003 INFO 27440 --- [Schedule-Task-3] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:Schedule-Task-3,方法開(kāi)始時(shí)間為:11:35:25
2020-07-07 11:35:35.001 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為: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)前線(xiàn)程為:Schedule-Task-1,方法開(kāi)始時(shí)間為:11:35:40
2020-07-07 11:35:40.002 INFO 27440 --- [Schedule-Task-5] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為:Schedule-Task-5,方法開(kāi)始時(shí)間為:11:35:40
2020-07-07 11:35:50.002 INFO 27440 --- [Schedule-Task-1] c.e.multithreading.service.TestService  : 當(dāng)前線(xiàn)程為: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)前線(xiàn)程為:Schedule-Task-5,方法結(jié)束時(shí)間為:11:35:50

關(guān)于Springboot實(shí)現(xiàn)集成定時(shí)器和多線(xiàn)程異步處理就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI