package com.example.demo.async;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author yg
* @description TODO
* @date 2023-06-14 22:31
*/
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfiguration {
@Bean("doSomethingExecutor")
public Executor doSomethingExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数:线程池创建时候初始化的线程数
executor.setCorePoolSize(10);
// 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(20);
// 缓冲队列:用来缓冲执行任务的队列
executor.setQueueCapacity(500);
// 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
// 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setThreadNamePrefix("do-something-");
// 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
executor.initialize();
log.info("doSomethingExecutor 初始化完毕,executor.getCorePoolSize() = {}", executor.getCorePoolSize());
return executor;
}
}
线程方法使用:
1,开启异步
注解开启 @EnableAsync
2,异步线程使用
方法添加 @Async("doSomethingExecutor")
@Async("doSomethingExecutor")
public CompletableFuture<String> doSomething1(String message) throws InterruptedException {
log.info("do something1: {}", message);
Thread.sleep(1000);
return CompletableFuture.completedFuture("do something1: " + message);
//return AsyncResult.forValue("do something11: " + message);
}
@Async("doSomethingExecutor")
public CompletableFuture<String> doSomething2(String message) throws InterruptedException {
log.info("do something2: {}", message);
Thread.sleep(1000);
return CompletableFuture.completedFuture("; do something2: " + message);
}
@Async("doSomethingExecutor")
public CompletableFuture<String> doSomething3(String message) throws InterruptedException {
log.info("do something3: {}", message);
Thread.sleep(1000);
return CompletableFuture.completedFuture("; do something3: " + message);
}
3,调用方法
@SneakyThrows
@ApiOperation("异步 有返回值")
@GetMapping("/open/somethings")
public String somethings() {
CompletableFuture<String> createOrder = asyncService.doSomething1("create order");
CompletableFuture<String> reduceAccount = asyncService.doSomething2("reduce account");
CompletableFuture<String> saveLog = asyncService.doSomething3("save log");
// 等待所有任务都执行完
CompletableFuture.allOf(createOrder, reduceAccount, saveLog).join();
// 获取每个任务的返回结果
String result = createOrder.get() + reduceAccount.get() + saveLog.get();
return result;
}
返回结果:
do something1: create order; do something2: reduce account; do something3: save log
打印结果
2023-06-15 23:36:43.609 INFO 16016 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-06-15 23:36:43.609 INFO 16016 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-06-15 23:36:43.611 INFO 16016 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2023-06-15 23:36:43.635 INFO 16016 --- [nio-8080-exec-1] com.example.demo.async.AsyncService : do something1: create order
2023-06-15 23:36:44.655 INFO 16016 --- [nio-8080-exec-1] com.example.demo.async.AsyncService : do something2: reduce account
2023-06-15 23:36:45.669 INFO 16016 --- [nio-8080-exec-1] com.example.demo.async.AsyncService : do something3: save log