Async注解有什么缺点
缺点
@Async中关于线程池的使用部分在AsyncExecutionInterceptor中,在这个类中有一个getDefaultExecutor方法, 当我们没有做过自定义线程池的时候,就会用SimpleAsyncTaskExecutor这个线程池。
@Override protected Executor getDefaultExecutor(BeanFactory beanFactory) { Executor defaultExecutor = super.getDefaultExecutor(beanFactory); return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor()); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- SimpleAsyncTaskExecutor这玩意坑很大,其实他并不是真的线程池,它是不会重用线程的,每次调用都会创建一个新的线程,也没有最大线程数设置。并发大的时候会产生严重的性能问题。
- 在没有Spring boot的加持下,异步任务使用了一个线程池,它的corePoolSize=8, 阻塞队列采用了无界队列LinkedBlockingQueue。一旦采用了这样的组合,最大线程数就会形同虚设,因为超出8个线程的任务,将全部会被放到无界队列里。
- 因此我们对于@Async注解的使用是极度容易造成OOM的,更何况我们对于自定义线程池都不敢说完全了解,就不要使用该注解啦。
## 如何解决
```java
@Configuration
@EnableAsync
public class AsyncExecutorConfig {
@Bean("registerSuccessExecutor")
public Executor caseStartFinishExecutor() {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("registerSuccessExecutor-%d").build();
ExecutorService executorService = new ThreadPoolExecutor(100, 200,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
return executorService;
}
}我们通过@Async(“registerSuccessExecutor”)便可以将异步线程池指定为我们自定义的线程池,也就一定程度上的弥补该注解的问题。
扩展知识
时间监听机制(观察者模式)
Spring Event是Spring框架中的一种事件机制,它允许不同组件之间通过事件的方式进行通信。Spring框架中的事件机制建立在观察者模式的基础上,允许应用程序中的组件注册监听器来监听特定类型的事件,并在事件发生时执行相应的操作。
Spring Event的使用需要定义以下三个内容:
- 事件(Event):事件是一个普通的Java对象,用于封装关于事件发生的信息。通常,事件类会包含一些数据字段,以便监听器能够获取事件的相关信息。
- 事件发布者(Event Publisher):事件发布者是负责触发事件并通知所有注册的监听器的组件。
- 事件监听器(Event Listener):事件监听器是负责响应特定类型事件的组件。它们实现了一个接口或者使用注解来标识自己是一个事件监听器,并定义了在事件发生时需要执行的逻辑。
如何实现
1 |
|
默认情况下,Spring Event的调用时同步调用的。如果想要实现异步调用,也是支持的,最简单的方式就是借助@Async 注解对监听器进行标注,当然实际情况必然是不建议的,我们应当使用自定义线程池进行异步通知。
1 |
|
好处
- 代码解耦:通过使用事件机制,组件之间不需要直接互相依赖,从而减少了代码之间的耦合度。这使得代码更易于维护和扩展。
- 职责清晰:事件机制有助于将应用程序拆分为更小的模块,每个模块只关心要做的事儿,和关心自己需要监听的事件就行了。
- 异步处理:Spring Event机制支持异步事件处理,这意味着可以将事件的处理分发到不同的线程,提高了系统的响应性。
- 一对多:Spring Event是观察者模式的一种实现,他的一个事件可以有多个监听者,所以当我们有多个模块之间需要通信时,可以直接发一个事件出去,让监听者各自监听即可。
Async注解有什么缺点
http://lzhnet.top/2023/06/12/Async注解有什么缺点/