很多人會直接只用@Async來執行異步操作。但是這裏面有一個問題,如果都是用spring的默認實現,是有坑的。
當我們開啓 EnableAsync註解 就可以使用@Async註解來執行異步操作了。
我們現在通過EnableAsync註解去打開spring異步世界的坑。
走JDK的動態代理:
最終走到這兒來了:AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)
問題就在這裏,如果我們自己沒有定義 Executor,也就是上面從容器beanFactory 中拿不到Executor 那麼就會使用--SimpleAsyncTaskExecutor,這玩意兒實際上根本不是線程池!!!!!
請看它的 doExecute 方法,直接new新的線程。
所以這玩意兒一直都是在創建新的 線程執行任務。。。。。
修改方式:
方案1.@Async 指定我們自己的線程池執行:@Async("自己線程池beanName")
方案2:回到AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory) 方法,看它如何獲取線程池的:
要麼我們自己配置一個TaskExecutor, 要麼我們把我自己配置的線程池的名字叫做 taskExecutor 。這個常量的值:
DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor",這樣可以避免使用SimpleAsyncTaskExecutor。
方案3:實現 AsyncConfigurer 接口作爲一個配置類交給spring管理,通過 getAsyncExecutor 方法配置異步線程池。