springboot-線程池簡單使用


最近做項目,關於訂單創建時候因為需要調用遠程http服務獲取數據,然后校驗並寫入數據庫和修改數據庫,

導致接口效率低,所以想到實現異步操作的方式解決。

在調用遠程接口成功的時候即認為接口處理成功,返回給前段正確,並開啟線程進行數據的寫入和修改

1)添加配置類

 1 package com.fieldsales.pos.config;
 2 
 3 import lombok.Data;
 4 import org.springframework.boot.context.properties.ConfigurationProperties;
 5 import org.springframework.context.annotation.Bean;
 6 import org.springframework.context.annotation.Configuration;
 7 import org.springframework.scheduling.annotation.EnableAsync;
 8 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 9 
10 import java.util.concurrent.Executor;
11 import java.util.concurrent.ThreadPoolExecutor;
12 
13 /**
14  * @author :CX
15  * @Date :Create in 2019/3/29 10:42
16  * @Effect :線程池配置類
17  */
18 @Configuration
19 @EnableAsync
20 @ConfigurationProperties(prefix = "async")
21 @Data
22 public class ExecutorConfig {
23 
24     private int corePoolSize;
25     private int maxPoolSize;
26     private int queueCapacity;
27     private String namePrefix;
28 
29 
30     @Bean(name = "asyncServiceExecutor")
31     public Executor asyncServiceExecutor() {
32         System.err.println("初始化線程池-----");
33         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
34         //配置核心線程數
35         executor.setCorePoolSize(corePoolSize);
36         //配置最大線程數
37         executor.setMaxPoolSize(maxPoolSize);
38         //配置隊列大小
39         executor.setQueueCapacity(queueCapacity);
40         //配置線程池中的線程的名稱前綴
41         executor.setThreadNamePrefix(namePrefix);
42 
43         // rejection-policy:當pool已經達到max size的時候,如何處理新任務
44         // CALLER_RUNS:不在新線程中執行任務,而是有調用者所在的線程來執行
45         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
46         //執行初始化
47         executor.initialize();
48         return executor;
49     }
50 
51 
52 }

 

2)在配置文件中添加相應配置

 1 #線程池配置
 2 async:
 3   # 配置核心線程數
 4   corePoolSize: 30
 5   # 配置最大線程數
 6   maxPoolSize: 30
 7   # 配置隊列大小
 8   queueCapacity: 9999
 9   # 配置線程池中的線程的名稱前綴
10   namePrefix: async-createOrderService-

 

3) 注入使用

 1     //注入線程池
 2     @Autowired
 3     private Executor asyncServiceExecutor;
 4 
 5 //上方代碼接口調用成功 略
 6                 // 開啟線程寫入數據庫數據
 7                 asyncServiceExecutor.execute(new Runnable() {
 8                     @Override
 9                     public void run() {
10 
11                         //標記數據是否正常寫入 , 如果數據寫入數據庫異常,則每10S寫出一次異常日志
12                         boolean isAddOrder = false;
13                         // 數據寫入的時間
14                         String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ").format(new Date());
15 
16                       try{
17                    //開啟事物寫入數據
18                         } catch (Throwable throwable) {
19 // 接口成功但是寫入數據失敗,則間隔拋出異常
20                             while (true) {
21                                 logger.error("嚴重錯誤------------------------------------------------------------");
22                                 logger.error("訂單【" + resultdata.get("orderno").toString() + "】銷售成功,但寫入現場售票數據庫失敗!");
23                                 logger.error("詳情表: :" + JSON.toJSONString(orderInfos));
24                                 logger.error("訂單表:" + JSON.toJSONString(tkttransFormModel));
25                                 logger.error("異常信息:" + throwable.getMessage());
26                                 logger.error("錯誤時間:" + format);
27                                 try {
28                                     Thread.sleep(20000);
29                                 } catch (InterruptedException e) {
30                                     e.printStackTrace();
31                                 }
32                             }
33                         }
34                     }
35                 });
36                 return HSResponse.ok(responsMap);        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM