当前位置:网站首页>SSM-使用@Async和创建ThreadPoolTaskExecutor线程池
SSM-使用@Async和创建ThreadPoolTaskExecutor线程池
2022-07-28 19:16:00 【胡安民】
线程池具体配置建议请看 : http://t.csdn.cn/nWaGH
直接在项目中使用的线程池
在applicationContext.xml里添加
<bean id="userService" class="com.ssm.service.impl.UserServiceImpl">
<property name="executor">
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadNamePrefix" value="user-"/>
<property name="corePoolSize" value="20"/>
<property name="maxPoolSize" value="20"/>
<property name="keepAliveSeconds" value="300"/>
<property name="queueCapacity" value="100"/>
</bean>
</property>
</bean>
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
private AsyncTaskExecutor executor;
public void setExecutor(AsyncTaskExecutor executor) {
this.executor = executor;
}
public void getUserList() {
//多线程
executor.execute(()->{
System.out.println("========");
});
}
}
配置异步@Async
在applicationContext.xml同目录下创建文件threadPool.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!-- 开启异步,并引入线程池 该标签用于启用检测任何 Spring管理的bean上的@Async和@Scheduled注解 -->
<task:annotation-driven executor="threadPool" />
<!-- 定义线程池 -->
<bean id="threadPool" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数,这个是全系统使用所以根据系统的访问量进行计算 (峰值秒访问量*1.5) -->
<property name="corePoolSize" value="1000" />
<!-- 最大线程数,默认为Integer.MAX_VALUE -->
<property name="maxPoolSize" value="1000" />
<!-- 队列最大长度建议设置(corePoolSize*2) -->
<property name="queueCapacity" value="2000" />
<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
<property name="keepAliveSeconds" value="300" />
<!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 -->
<property name="rejectedExecutionHandler">
<!-- CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前的被丢弃的任务。-->
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
</beans>
然后后在applicationContext.xml中引入threadPool.xml:
<import resource="threadPool.xml" />
测试
定义的异步方法不能与被调用的异步方法在同一个类中,否则无效
这里模拟取消订单后发短信,有两个发送短信的方法
@Service
public class TranTest2Service {
// 发送提醒短信 1
@Async("threadPool")
public void sendMessage1() throws InterruptedException {
System.out.println("发送短信方法---- 1 执行开始");
Thread.sleep(5000); // 模拟耗时
System.out.println("发送短信方法---- 1 执行结束");
}
// 发送提醒短信 2
@Async("threadPool")
public void sendMessage2() throws InterruptedException {
System.out.println("发送短信方法---- 2 执行开始");
Thread.sleep(2000); // 模拟耗时
System.out.println("发送短信方法---- 2 执行结束");
}
}
调用发短信的方法
@Autowired
private TranTest2Service tranTest2Service;
// 订单处理任务
@GetMapping(path = "/orderTask")
public void orderTask() throws InterruptedException {
tranTest2Service.sendMessage1(); // 发短信的方法 1
tranTest2Service.sendMessage2(); // 发短信的方法 2
}
使用@Async效果
不使用@Async效果
基于@Async返回值的调用
@Async("threadPool")
public Future<String> asyncMethodWithReturnType() {
System.out.println("Execute method asynchronously - "
+ Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
以上示例可以发现,返回的数据类型为Future类型,其为一个接口。具体的结果类型为AsyncResult, 这个是需要注意的地方。
调用返回结果的异步方法示例:
public void testAsyncAnnotationForMethodsWithReturnType()
throws InterruptedException, ExecutionException {
System.out.println("Invoking an asynchronous method. "
+ Thread.currentThread().getName());
Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();
//阻塞全部线程完成后,获取线程返回的内容
future.get()
}
基于@Async调用中的异常处理机制
在异步方法中,如果出现异常,对于调用者caller而言,是无法感知的。如果确实需要进行异常处理,则按照如下方法来进行处理:
<task:annotation-driven executor="exceptionHandlingTaskExecutor" />
<bean id="exceptionHandlingTaskExecutor" class=" com.ssm.service.impl.ExceptionHandlingAsyncTaskExecutor">
<constructor-arg ref="threadPool" />
</bean>
public class ExceptionHandlingAsyncTaskExecutor implements AsyncTaskExecutor {
private AsyncTaskExecutor executor;
public ExceptionHandlingAsyncTaskExecutor(AsyncTaskExecutor executor) {
this.executor = executor;
}
//用独立的线程来包装,@Async其本质就是如此
@Override
public void execute(Runnable task) {
executor.execute(createWrappedRunnable(task));
}
@Override
public void execute(Runnable task, long startTimeout) {
//用独立的线程来包装,@Async其本质就是如此
executor.execute(createWrappedRunnable(task), startTimeout);
}
@Override
public Future submit(Runnable task) {
//用独立的线程来包装,@Async其本质就是如此。
return executor.submit(createWrappedRunnable(task));
}
@Override
public Future submit(final Callable task) {
//用独立的线程来包装,@Async其本质就是如此。
return executor.submit(createCallable(task));
}
private Callable createCallable(final Callable task) {
return new Callable() {
@Override
public Object call() throws Exception {
try {
return task.call();
} catch (Exception ex) {
handle(ex);
throw ex;
}
}
};
}
private Runnable createWrappedRunnable(final Runnable task) {
return new Runnable() {
@Override
public void run() {
try {
task.run();
} catch (Exception ex) {
handle(ex);
}
}
};
}
private void handle(Exception ex) {
//具体的异常逻辑处理的地方
System.err.println("Error during @Async execution: " + ex);
}
}

边栏推荐
- 【input 身份证号】星号 代替,input 切割成 多个 小格格(类似)
- unity-shader-1
- New development of letinar in Korea: single lens 4.55G, light efficiency up to 10%
- Looking at SQL optimization from the whole process of one query
- How to modify the ID of NetApp expansion enclosure disk shelf
- Introduction to redis I: redis practical reading notes
- DeiT:注意力Attention也能蒸馏
- C foundation 8-reflection and dependency injection
- C # basic 4-written examination question 1
- Ask if you don't understand, and quickly become an advanced player of container service!
猜你喜欢

How to use redis to realize things and locks?

Moco V1: the visual field can also be self supervised

Unity3d tutorial notes - unity initial 04

Alibaba cloud MSE supports go language traffic protection

What is data center? What value does the data center bring_ Light spot technology

Thinking and summary of R & D Efficiency

什么是 CI/CD? | 实现更快更好的软件交付

JS page black and white background switch JS special effect

云原生编程挑战赛火热开赛,51 万奖金等你来挑战!

Integrating database Ecology: using eventbridge to build CDC applications
随机推荐
蓝队入门之效率工具篇
Oracle library access is slow. Why?
Algorithm interview high frequency problem solving guide [1]
4.2 Virtual Member Functions
PostgreSQL数据库删库前是不是需要把所有连接断开才能删除?
Guo Mingxuan: meta contraction is conducive to the development of VR competitors, and apple XR headshow will change the industry rules
数据库--explain的使用
既要便捷、安全+智能,也要颜值,萤石发布北斗星人脸锁DL30F和极光人脸视频锁Y3000FV
Lvs+keepalived high availability deployment practical application
C foundation 8-reflection and dependency injection
怎样搭建企业内部维基百科
dll反编译(反编译加密dll)
什么是 CI/CD? | 实现更快更好的软件交付
Tested interviewed Zuckerberg: reveal more details of four VR prototypes
Introduction to singleton mode
Explain the script data transmission and notification in unity
A 58 year old native of Anhui Province, he has become the largest IPO investor in Switzerland this year
3D laser slam: Interpretation of logo-loam paper - Introduction
【周周有奖】云原生编程挑战赛“边缘容器”赛道邀你来战!
Integrating database Ecology: using eventbridge to build CDC applications