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);        
原文地址:https://www.cnblogs.com/cx987514451/p/10621817.html