2 回答

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊
我想限制可能的線程數(shù),同時(shí)不丟失任何消息。我的這個(gè)要求沒有從現(xiàn)有的答案中得到滿足,我找到了另一種方法來做到這一點(diǎn)。因此,將其發(fā)布為答案:
我制作了一個(gè) 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(){
....
}
鑒于當(dāng)線程忙且隊(duì)列已滿時(shí),新任務(wù)會(huì)被拒絕,
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())
幫助我,當(dāng)我的 5 個(gè)線程很忙時(shí),我的調(diào)用者線程將執(zhí)行任務(wù),并且由于我的調(diào)用者線程在異步函數(shù)中,它不會(huì)執(zhí)行任何新任務(wù)。因此,我不會(huì)在不增加隊(duì)列大小的情況下放棄我的任務(wù)。

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