乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      SpringBoot為異步任務(wù)規(guī)劃線程池及實現(xiàn)定時任務(wù)

       碼農(nóng)9527 2021-09-06

          上一篇文章中我們學會了如何使用異步的方式去執(zhí)行任務(wù),在實際的開發(fā)當中,應(yīng)用服務(wù)的并發(fā)量比較大時,頻繁的創(chuàng)建和銷毀線程是非常消耗性能和資源的,并且一個進程能夠創(chuàng)建的線程數(shù)量也是有上限的。為了解決這些問題,我們需要使用線程池來管理這些業(yè)務(wù)線程。

          如果沒有配置線程池,springboot會自動配置一個ThreadPoolTaskExecutor線程池到bean當中。

      spring:
        task:
         execution:
        pool:
       # 核心線程數(shù)
       core-size: 8
       # 最大線程數(shù)
       max-size: 16
       # 空閑線程存活時間
       keep-alive: 60s
       # 是否允許核心線程超時
       allow-core-thread-timeout: true
       # 線程隊列數(shù)量
       queue-capacity: 100
        shutdown:
       # 關(guān)閉等待
       await-termination: false
       await-termination-period:
        # 前綴名稱
        thread-name-prefix: task-1234567891011121314151617181920復制代碼類型:[java]

          自定義線程池

          有時候我們希望將線程放到不同的線程池進行分類,或者有一些個性化的需求。這時我們就可以創(chuàng)建一個線程池配置類并配置一個任務(wù)線程池對象。

      package com.example.demo.configuration;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;import java.util.concurrent.ThreadPoolExecutor;@Configurationpublic class TaskConfiguration { @Bean("taskExecutor")
       public Executor taskExecutor() {  // 創(chuàng)建線程池
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();  // 核心線程數(shù)、線程池創(chuàng)建時候初始化的線程數(shù),最小線程數(shù)
        executor.setCorePoolSize(10);  // 線程池最大的線程數(shù)(只有在緩沖隊列滿了之后,才會申請超過核心線程數(shù)的線程)
        executor.setMaxPoolSize(20);  // 用來緩沖執(zhí)行任務(wù)的隊列
        executor.setQueueCapacity(200);  // 超過了核心線程之外的線程,在空閑時間到達之后,沒活干的線程會被銷毀
        executor.setKeepAliveSeconds(60);  // 定位處理任務(wù)所在的線程池
        executor.setThreadNamePrefix("taskExecutor-");  // 線程池對任務(wù)的Reject策略,當線程池運行飽和,或者線程池處于shutdown臨界狀態(tài)時,用來拒絕一個任務(wù)的執(zhí)行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());  return executor;
       }
      }123456789101112131415161718192021222324252627282930復制代碼類型:[java]

          注釋中提到的Reject策略一共有四種:

          AbortPolicy

          將拋出RejectedExecutionException

          CallerRunsPolicy

          直接在execute方法的調(diào)用線程中運行被拒絕的任務(wù)

          DiscardOldestPolicy

          放棄最舊的未處理請求,然后重試execute

          DiscardPolicy

          默認情況下它將丟棄被拒絕的任務(wù)

          創(chuàng)建AsyncExecutorTask類繼承TaskMethodProvider,@Async注解需要指定前面配置的線程池的名稱taskExecutor:

      package com.example.demo.task;import org.springframework.scheduling.annotation.Async;import org.springframework.scheduling.annotation.AsyncResult;import org.springframework.stereotype.Component;@Componentpublic class AsyncExecutorTask extends TaskMethodProvider { @Async("taskExecutor")
       public void doTaskOneCallback() throws Exception {  super.taskOne();
        System.out.println("任務(wù)一,當前線程:" + Thread.currentThread().getName());  new AsyncResult<>("任務(wù)一完成");
       } @Async("taskExecutor")
       public void doTaskTwoCallback() throws Exception {  super.taskTwo();
        System.out.println("任務(wù)二,當前線程:" + Thread.currentThread().getName());  new AsyncResult<>("任務(wù)二完成");
       } @Async("taskExecutor")
       public void doTaskThreeCallback() throws Exception {  super.taskThree();
        System.out.println("任務(wù)三,當前線程:" + Thread.currentThread().getName());  new AsyncResult<>("任務(wù)三完成");
       }
      }123456789101112131415161718192021222324252627282930復制代碼類型:[java]

          編寫單元測試:

      package com.example.demo;import com.example.demo.task.AsyncExecutorTask;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import static java.lang.Thread.sleep;@SpringBootTestpublic class Task { @Autowired
       private AsyncExecutorTask task; @Test
       public void testAsyncExecutorTask() throws Exception {
        task.doTaskOneCallback();
        task.doTaskTwoCallback();
        task.doTaskThreeCallback();
      
        sleep(10 * 1000L);
       }
      }1234567891011121314151617181920212223復制代碼類型:[java]

          執(zhí)行單元測試:

          線程池成功執(zhí)行異步任務(wù)。

          關(guān)閉線程池

          在原有TaskConfiguration.java代碼的基礎(chǔ)上添加:

      executor.setWaitForTasksToCompleteOnShutdown(true);
      executor.setAwaitTerminationSeconds(60);12復制代碼類型:[java]

          setWaitForTasksToCompleteOnShutdown(true):

          線程池關(guān)閉的時候等待所有任務(wù)都完成后,再繼續(xù)銷毀其他的Bean,使異步任務(wù)的銷毀就會先于數(shù)據(jù)庫連接池對象的銷毀。

          setAwaitTerminationSeconds(60):

          設(shè)置線程任務(wù)等待時間,超過這個時間任務(wù)還沒有銷毀就強制銷毀。

          @Scheduled實現(xiàn)定時任務(wù)

          @Scheduled實現(xiàn)定時任務(wù)是SpringBoot自身提供的功能,不需要maven依賴,只需要在啟動類上添加@EnableScheduling注解,即可開啟定時任務(wù)。

          下面來實現(xiàn)一個定時任務(wù),在task文件夾下創(chuàng)建ScheduledTask.java:

      package com.example.demo.task;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import java.util.Date;@Componentpublic class ScheduledTask { // 方法執(zhí)行完成后3秒再開始執(zhí)行
       @Scheduled(fixedDelay = 3000)
       public void fixedDelayJob() throws InterruptedException {
        System.out.println("fixedDelay 開始:" + new Date());
        Thread.sleep(10 * 1000);
        System.out.println("fixedDelay 結(jié)束:" + new Date());
       } // 每隔2秒
       @Scheduled(fixedRate = 2000)
       public void fixedRateJob() throws InterruptedException {
        System.out.println("===========fixedRate 開始:" + new Date());
        Thread.sleep(5 * 1000);
        System.out.println("===========fixedRate 結(jié)束:" + new Date());
       } // 每隔7秒執(zhí)行一次
       @Scheduled(cron = "0/7 * * * * ? ")
       public void cronJob() {
        System.out.println("=========================== ...>>cron...." + new Date());
       }
      }12345678910111213141516171819202122232425262728293031復制代碼類型:[java]

          如果只是這樣編寫所有的定時任務(wù)使用的都是一個線程,不能得到我們想要的結(jié)果,所以需要解決解決定時任務(wù)單線程運行的問題。

          在config文件夾下創(chuàng)建ScheduleConfig.java:

      package com.example.demo.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar;import java.util.concurrent.Executor;import java.util.concurrent.Executors;@Configuration@EnableSchedulingpublic class ScheduleConfig implements SchedulingConfigurer { @Override
       public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(scheduledTaskExecutor());
       } @Bean
       public Executor scheduledTaskExecutor() {  // 線程池的大小為3
        return Executors.newScheduledThreadPool(3);
       }
      }1234567891011121314151617181920212223242526復制代碼類型:[java]

          執(zhí)行代碼,得到打印信息:

          在@Scheduled標簽后面括號中的fixedDelay和fixedRate單位都是毫秒,區(qū)別是fixedDelay任務(wù)執(zhí)行完畢后一段時間再次執(zhí)行而fixedRate則是每隔多長時間就執(zhí)行一次。

          @Scheduled標簽中還可以使用cron表達式:

      第一位
      秒(0-59)
      第二位
      分(0-59)
      第三位
      小時(0-23)
      第四位
      日(1-31)
      第五位
      月份(1-12)
      第六位
      星期幾(1-7)
      第七位
      年(1970-2099,也可以為空)

          cron特殊符號:

      *
      每秒,每分,每天,每月,每年..
      ?
      出現(xiàn)在日期和星期這兩個位置
      -
      表達一個范圍
      ,
      表達一個列表值
      /
      x/y,x是開始值,y是步長(0/3,0秒開始,每3秒...)

        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多