<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
執行緒池的作用
在高並行環境下,不斷的分配新資源,可能導致系統資源耗盡。所以為了避免這個問題,我們為非同步任務規劃一個執行緒池。當然,如果沒有設定執行緒池的話,springboot會自動設定一個ThreadPoolTaskExecutor 執行緒池到bean當中。
# 核心執行緒數 spring.task.execution.pool.core-size=8 # 最大執行緒數 spring.task.execution.pool.max-size=16 # 空閒執行緒存活時間 spring.task.execution.pool.keep-alive=60s # 是否允許核心執行緒超時 spring.task.execution.pool.allow-core-thread-timeout=true # 執行緒佇列數量 spring.task.execution.pool.queue-capacity=100 # 執行緒關閉等待 spring.task.execution.shutdown.await-termination=false spring.task.execution.shutdown.await-termination-period= # 執行緒名稱字首 spring.task.execution.thread-name-prefix=task-
在springboot組態檔中加入上面的設定,即可實現ThreadPoolTaskExecutor 執行緒池。
有的時候,我們希望將系統內的一類任務放到一個執行緒池,另一類任務放到另外一個執行緒池,所以使用Spring Boot自帶的任務執行緒池就捉襟見肘了。下面介紹自定義執行緒池的方法。
建立一個 執行緒池設定類 TaskConfiguration ,並設定一個 任務執行緒池物件 taskExecutor。
@Configuration public class TaskConfiguration { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(200); executor.setKeepAliveSeconds(60); executor.setThreadNamePrefix("taskExecutor-"); executor.setRejectedExecutionHandler(new CallerRunsPolicy()); return executor; } }
上面我們通過使用 ThreadPoolTaskExecutor 建立了一個 執行緒池,同時設定了以下這些引數:
執行緒池屬性 | 屬性的作用 | 上文程式碼設定初始值 |
---|---|---|
核心執行緒數CorePoolSize | 執行緒池建立時候初始化的執行緒數,最小執行緒數 | 10 |
最大執行緒數MaxPoolSize | 執行緒池最大的執行緒數,只有在緩衝佇列滿了之後,才會申請超過核心執行緒數的執行緒 | 20 |
緩衝任務佇列QueueCapacity | 用來緩衝執行任務的佇列 | 200 |
允許執行緒的空閒時間KeepAliveSeconds | 超過了核心執行緒之外的執行緒,在空閒時間到達之後,沒活幹的執行緒會被銷燬 | 60秒 |
執行緒池名的字首 ThreadNamePrefix | 可以用於定位處理任務所在的執行緒池 | taskExecutor- |
執行緒池對任務的Reject策略RejectedExecutionHandler | 當執行緒池執行飽和,或者執行緒池處於shutdown臨界狀態時,用來拒絕一個任務的執行 | CallerRunsPolicy |
Reject策略預定義有四種:
建立 AsyncExecutorTask類,三個任務的設定和 AsyncTask 一樣,不同的是 @Async 註解需要指定前面設定的 執行緒池的名稱 taskExecutor。
@Component public class AsyncExecutorTask extends AbstractTask { @Async("taskExecutor") public Future<String> doTaskOneCallback() throws Exception { super.doTaskOne(); System.out.println("任務一,當前執行緒:" + Thread.currentThread().getName()); return new AsyncResult<>("任務一完成"); } @Async("taskExecutor") public Future<String> doTaskTwoCallback() throws Exception { super.doTaskTwo(); System.out.println("任務二,當前執行緒:" + Thread.currentThread().getName()); return new AsyncResult<>("任務二完成"); } @Async("taskExecutor") public Future<String> doTaskThreeCallback() throws Exception { super.doTaskThree(); System.out.println("任務三,當前執行緒:" + Thread.currentThread().getName()); return new AsyncResult<>("任務三完成"); } }
在 單元測試 用例中,注入 AsyncExecutorTask 物件,並在測試用例中執行 doTaskOne(),doTaskTwo(),doTaskThree() 三個方法。
@SpringBootTest public class AsyncExecutorTaskTest { @Autowired private AsyncExecutorTask task; @Test public void testAsyncExecutorTask() throws Exception { task.doTaskOneCallback(); task.doTaskTwoCallback(); task.doTaskThreeCallback(); sleep(30 * 1000L); } }
執行一下上述的 單元測試,可以看到如下結果:
開始做任務一
開始做任務三
開始做任務二
完成任務二,耗時:3905毫秒
任務二,當前執行緒:taskExecutor-2
完成任務一,耗時:6184毫秒
任務一,當前執行緒:taskExecutor-1
完成任務三,耗時:9737毫秒
任務三,當前執行緒:taskExecutor-3
執行上面的單元測試,觀察到 任務執行緒池 的 執行緒池名的字首 被列印,說明 執行緒池 成功執行 非同步任務!
由於在應用關閉的時候非同步任務還在執行,導致類似 資料庫連線池 這樣的物件一併被 銷燬了,當 非同步任務 中對 資料庫 進行操作就會出錯。
解決方案如下,重新設定執行緒池設定物件,新增執行緒池 setWaitForTasksToCompleteOnShutdown() 和 setAwaitTerminationSeconds() 設定:
@Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler(); executor.setPoolSize(20); executor.setThreadNamePrefix("taskExecutor-"); executor.setWaitForTasksToCompleteOnShutdown(true); executor.setAwaitTerminationSeconds(60); return executor; }
非同步任務** 的 銷燬 就會先於 資料庫連線池物件 的銷燬。
到此這篇關於springboot為非同步任務規劃自定義執行緒池的實現的文章就介紹到這了,更多相關springboot非同步自定義執行緒池內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45