SpringBoot項目中@Async方法沒有執行的問題分析


現象: 
    1. 表面現象: 方法中輸出的日志, 日志文件中找不到, 也沒有任何報錯(即@Async標注的方法沒有執行, 也沒有報錯)
    2. 分析現象: 日志中某個時刻之后沒有了task-xxx線程的日志
 
原因: 
    @Async異步方法默認使用Spring創建ThreadPoolTaskExecutor(參考TaskExecutionAutoConfiguration), 
其中默認核心線程數為8, 默認最大隊列和默認最大線程數都是Integer.MAX_VALUE. 創建新線程的條件是隊列填滿時, 而
這樣的配置隊列永遠不會填滿, 如果有@Async注解標注的方法長期占用線程(比如HTTP長連接等待獲取結果), 
在核心8個線程數占用滿了之后, 新的調用就會進入隊列, 外部表現為沒有執行.

解決:
    手動配置相應屬性即可. 比如
    spring.task.execution.pool.queueCapacity=4
    spring.task.execution.pool.coreSize=20

備注: 
    此處沒有配置maxSize, 仍是默認的Integer.MAX_VALUE. 如果配置的話, 請考慮達到最大線程數時的處理策略(JUC包查找RejectedExecutionHandler的實現類)
    (默認為拒絕執行AbortPolicy, 即拋出異常)
    
    AbortPolicy: 直接拋出java.util.concurrent.RejectedExecutionException異常
    CallerRunsPolicy: 主線程直接執行該任務,執行完之后嘗試添加下一個任務到線程池中,可以有效降低向線程池內添加任務的速度
    DiscardOldestPolicy: 拋棄舊的任務
    DiscardPolicy: 拋棄當前任務
    
截圖:
    1. ThreadPoolTaskExecutor
    2. SpringMonitor的配置屬性
    3. SpringMonitor的Threads

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM