之前自己写了一个ThreadPoolTaskExecutor线程池样例,现在基于CompletableFuture写法,记录一下。
一、配置类
1.1配置类根据自己的服务器参数自行配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线程池配置类 根据自己环境进行配置
*/
@Configuration
public class ExecutorConfig {
/**
* 核心线程数 自行设置
*/
private static final int CORE_POOL_SIZE = 15;
/**
* 最大线程数 自行设置
*/
private static final int MAX_POOL_SIZE = CORE_POOL_SIZE * 2 + 1;
@Bean(name="taskExecutor")
public ThreadPoolTaskExecutor taskExecutor(){
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
/**
* 此方法返回可用处理器的虚拟机的最大数量; 不小于1
* int core = Runtime.getRuntime().availableProcessors();
*/
//设置核心线程数
poolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
//设置最大线程数
poolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
//除核心线程外的线程存活时间
poolTaskExecutor.setKeepAliveSeconds(3);
//如果传入值大于0,底层队列使用的是LinkedBlockingQueue,否则默认使用SynchronousQueue
poolTaskExecutor.setQueueCapacity(40);
//线程名称前缀
poolTaskExecutor.setThreadNamePrefix("thread-execute");
//设置拒绝策略
poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return poolTaskExecutor;
}
}
二、主类开启异步注解@EnableAsync
@Slf4j
@SpringBootApplication
@EnableAsync
public class Zs3ServiceApplication {
public static void main(String[] args) {
try {
SpringApplicationBuilder builder = new SpringApplicationBuilder(Zs3ServiceApplication.class);
ApplicationContext context = builder.web(WebApplicationType.SERVLET).run(args);
} catch (Exception e) {
log.error("异常信息{}", e);
}
}
}
三、使用样例
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* @Author:
* @Description
* @Date: 下午5:14 2023/6/07
*/
@Slf4j
@Component
public class ExecutorTest {
@Autowired
private ExecutorConfig taskExecutor;
/**
* 异步方法一
*
* @param param
* @return
*/
@Async
public Map<String, Double> methodOne(int param) {
//编写自己的业务代码
Map<String, Double> map = new HashMap<>();
for (int i = 0; i < param; i++) {
map.put(i + "", (double) i);
}
return map;
}
/**
* 异步方法二
*
* @param param
* @return
*/
@Async
public List<Integer> methodTwo(int param) {
//编写自己的业务代码
List<Integer> list = new ArrayList<>();
for (int i = 0; i < param; i++) {
list.add(Integer.valueOf(i));
}
return list;
}
public void test() {
CompletableFuture<Map<String, Double>> methodOneFuture = CompletableFuture.supplyAsync(() -> methodOne(3), taskExecutor.taskExecutor());
CompletableFuture<List<Integer>> methodTwoFuture = CompletableFuture.supplyAsync(() -> methodTwo(3), taskExecutor.taskExecutor());
CompletableFuture.allOf(methodOneFuture, methodTwoFuture).join();
Map<String, Double> methodOneMap = new HashMap<>();
try {
methodOneMap = methodOneFuture.get();
} catch (InterruptedException e) {
log.error("调用methodOne--被中断异常");
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
log.error("调用methodOne--异常{}", e);
}
List<Integer> methodTwoMap = new ArrayList<>();
try {
methodTwoMap = methodTwoFuture.get();
} catch (InterruptedException e) {
log.error("调用methodTwo--被中断异常e");
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
log.error("调用methodTwo--异常{}", e);
}
}
}