亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用@Async注解限制線程數并等待最大線程數

使用@Async注解限制線程數并等待最大線程數

慕工程0101907 2022-11-10 16:24:39
我將 Spring 的 Java 配置與 AsyncConfigurer 一起使用:@Configuration@EnableAsyncpublic class AppConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();        executor.setCorePoolSize(2);        executor.setMaxPoolSize(2);        executor.setQueueCapacity(10);        executor.setThreadNamePrefix("MyExecutor-");        executor.initialize();        return executor;    }}現在假設我有一個帶有 @Async 注釋的方法,并假設它已經調用了 2 次并且 2 個線程仍在運行。根據我的理解,對它的任何新調用都將添加到容量為 10 的隊列中?,F在如果我收到第 11 個任務,它的行為會是什么?它會拒絕此處所述的任務:https ://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html ?還是調用者會等待隊列槽變空?我的要求是不要執行使用@Async 方法生成的固定數量的線程,并在達到最大線程數時讓調用者等待。如果我將 ConcurrentTaskExecutor 與特定大小的固定線程池一起使用,這會實現嗎?
查看完整描述

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 個線程很忙時,我的調用者線程將執行任務,并且由于我的調用者線程在異步函數中,它不會執行任何新任務。因此,我不會在不增加隊列大小的情況下放棄我的任務。


查看完整回答
反對 回復 2022-11-10
?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

根據 ThreadPoolExecutor 的工作原理,第 11 個任務將被拒絕,因為當隊列已滿時,執行程序會嘗試增加池大小,如果由于達到最大值而無法執行,則會拒絕該任務。
您可以在 Spring 文檔中找到相關信息:

主要思想是,當提交任務時,如果當前活動線程數小于核心大小,則執行程序首先嘗試使用空閑線程。如果已達到核心大小,則將任務添加到隊列中,只要其容量尚未達到。只有這樣,如果隊列的容量已經達到,執行程序才會創建一個超出核心大小的新線程。如果也達到了最大大小,則執行者拒絕該任務。

關于您的要求:

我的要求是不要執行使用@Async 方法生成的固定數量的線程,并在達到最大線程數時讓調用者等待。如果我將 ConcurrentTaskExecutor 與特定大小的固定線程池一起使用,這會實現嗎?

因此,因此增加隊列大小并為核心和最大池大小保留相同的值。OutOfMemoryError您也可以使用無界隊列,它是隊列大小參數的默認值,但要小心,因為如果隊列中堆積了太多任務 ,可能會導致這種情況。


查看完整回答
反對 回復 2022-11-10
  • 2 回答
  • 0 關注
  • 475 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號