原 spring boot 使用线程池执行异步方法
版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
本文链接:https://www.91mszl.com/zhangwuji/article/details/1252
一:线程池配置类。
package com.mszl.blog.config;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
// 自定义线程池配置
@Configuration
@EnableAsync // 为了扫描范围包下的所有 @Async注解
public class MyThreadConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor() {
return new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
10, // 空闲时间
TimeUnit.SECONDS, // 单位
new LinkedBlockingDeque<>(100), // 阻塞队列
Executors.defaultThreadFactory(), // 默认线程工程
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
}
}
二:controller层代码。
package com.mszl.blog.controller;
import java.util.concurrent.ExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mszl.blog.service.TestTaskService;
@RestController
public class AsynchronousController {
@Autowired
private TestTaskService testTask;
@PostMapping("/asynchronous")
public void aa() throws InterruptedException, ExecutionException {
System.out.println("start ................");
System.out.println(Thread.currentThread().getName());
testTask.task1();
System.out.println("end ................");
}
}
三:service接口层代码。
package com.mszl.blog.service;
import java.util.concurrent.ExecutionException;
public interface TestTaskService {
void task1() throws InterruptedException, ExecutionException;
}
四:service实现层代码。
package com.mszl.blog.service.impl;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.mszl.blog.service.TestTaskService;
@Service
public class TestTaskServiceImpl implements TestTaskService{
@Autowired
private ThreadPoolExecutor executor;
/**
* 业务场景:
* 1: 先执行1 新增用户操作,并且成功返回结果后,才往下继续执行 2 新增产品和3 新增组织的业务.
* 2: 2新增产品和3 新增组织,没有先后顺序,也无需返回结果。但必须都执行完成后整个异步方法才能结束。这个由allOf方法来控制。
*/
@Async("threadPoolExecutor") // 注意:1. 这里的threadPoolExecutor是线程池配置类中的方法名称; 2 @Async表示异步
public void task1() throws InterruptedException, ExecutionException {
Thread.sleep(3000); // 为了使异步效果更明显
System.out.println(Thread.currentThread().getName());
CompletableFuture future1=CompletableFuture.supplyAsync(() ->{
System.out.println("1. 新增用户");
return 100;
}, executor);
CompletableFuture future2=future1.thenAcceptAsync((res) -> {
System.out.println("2. 新增产品");
}, executor);
CompletableFuture future3=future1.thenAcceptAsync((res) -> {
System.out.println("3. 新增组织");
}, executor);
System.out.println("future1 返回结果:" + future1.get());
// 所有任务都完成
future1.allOf(future2, future3).get();
System.out.println("异步方法都成功了。");
}
}
执行结果(第一次执行):
start ................
http-nio-8001-exec-4
end ................
pool-1-thread-5
1. 新增用户
2. 新增产品
future1 返回结果:100
3. 新增组织
异步方法都成功了。
执行结果(第二次执行):
start ................
http-nio-8001-exec-6
end ................
pool-1-thread-1
1. 新增用户
future1 返回结果:100
2. 新增产品
3. 新增组织
异步方法都成功了。
2020-08-08 12:33:52 阅读(619)
名师出品,必属精品 https://www.91mszl.com
博主信息