在 Spring 中,使用 ThreadPoolTaskExecutor
時,如果執行緒池中的 任務佇列(Queue) 滿了,預設情況下並不會直接丟擲異常,而是會根據 RejectedExecutionHandler
的策略來決定如何處理被拒絕的任務。ThreadPoolTaskExecutor
繼承自 Java 的 ThreadPoolExecutor
,因此它使用了 ThreadPoolExecutor
中定義的拒絕策略來處理這種情況。
RejectedExecutionHandler
的預設策略
ThreadPoolTaskExecutor
使用的底層實現是 ThreadPoolExecutor
,它有四種處理拒絕任務的策略,預設情況下使用的是 AbortPolicy
。當任務佇列滿時,會觸發 java.util.concurrent.RejectedExecutionException
異常。以下是 ThreadPoolExecutor
支援的四種策略:
- AbortPolicy(預設):當任務無法被提交到執行緒池時,會丟擲
RejectedExecutionException
。 - CallerRunsPolicy:當任務無法被提交時,呼叫該任務的執行緒(提交任務的執行緒)會直接執行這個任務。這可能會影響應用程式的效能,因為原本用於提交任務的執行緒現在正在執行任務。
- DiscardPolicy:直接丟棄新提交的任務,不丟擲異常。
- DiscardOldestPolicy:丟棄佇列中最早提交但尚未被執行的任務,然後重新嘗試提交當前任務。
預設的處理行為
如果 ThreadPoolTaskExecutor
沒有設定自定義的拒絕策略,預設會使用 AbortPolicy
,也就是說,當任務佇列滿了之後,會丟擲 RejectedExecutionException
。這個異常表明執行緒池已經無法再接受新的任務,因為工作執行緒都已佔用且佇列已滿。
自定義拒絕策略
如果不想讓任務在佇列滿的時候直接丟擲異常,您可以自定義 ThreadPoolTaskExecutor
的拒絕策略。可以透過 setRejectedExecutionHandler()
方法來指定不同的策略。
例如:
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
這段程式碼將 CallerRunsPolicy
設定為拒絕策略,當佇列滿時,提交任務的執行緒會執行該任務而不是丟擲異常。
結論
在 ThreadPoolTaskExecutor
中,如果執行緒池的任務佇列滿了,預設情況下會丟擲 RejectedExecutionException
,這是由於使用了預設的 AbortPolicy
。您可以根據需要自定義拒絕策略以避免異常或選擇其他處理方式。