2 回答

TA貢獻1801條經驗 獲得超16個贊
我想限制可能的線程數,同時不丟失任何消息。我的這個要求沒有從現有的答案中得到滿足,我找到了另一種方法來做到這一點。因此,將其發布為答案:
我制作了一個 Executor Bean,如下所示:
@Bean(name = "CustomAsyncExecutor")
public Executor customThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(0);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("Async_Thread_");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
然后使用
@Async("CustomAsyncExecutor")
public void methodName(){
....
}
鑒于當線程忙且隊列已滿時,新任務會被拒絕,
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())
幫助我,當我的 5 個線程很忙時,我的調用者線程將執行任務,并且由于我的調用者線程在異步函數中,它不會執行任何新任務。因此,我不會在不增加隊列大小的情況下放棄我的任務。

TA貢獻1877條經驗 獲得超6個贊
根據 ThreadPoolExecutor 的工作原理,第 11 個任務將被拒絕,因為當隊列已滿時,執行程序會嘗試增加池大小,如果由于達到最大值而無法執行,則會拒絕該任務。
您可以在 Spring 文檔中找到相關信息:
主要思想是,當提交任務時,如果當前活動線程數小于核心大小,則執行程序首先嘗試使用空閑線程。如果已達到核心大小,則將任務添加到隊列中,只要其容量尚未達到。只有這樣,如果隊列的容量已經達到,執行程序才會創建一個超出核心大小的新線程。如果也達到了最大大小,則執行者拒絕該任務。
關于您的要求:
我的要求是不要執行使用@Async 方法生成的固定數量的線程,并在達到最大線程數時讓調用者等待。如果我將 ConcurrentTaskExecutor 與特定大小的固定線程池一起使用,這會實現嗎?
因此,因此增加隊列大小并為核心和最大池大小保留相同的值。OutOfMemoryError
您也可以使用無界隊列,它是隊列大小參數的默認值,但要小心,因為如果隊列中堆積了太多任務 ,可能會導致這種情況。
添加回答
舉報