私はAsyncConfigurerで春のJavaの設定を使用しています:
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {
@Override
public 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つのスレッドがまだ実行されているとします。私の理解あたりとしては、それへの新しいコールは、私は11日のタスクを受信した場合、何がそれの動作になりますさて、容量10と、キューに追加されますか?ここに述べたように、タスクを拒否します:https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html?またはキュースロットの発信者の待機は空取得するのだろうか?
私の要件は、スレッドの修正番号をexeedないために、スレッドの最大数に達した場合は、発信者の待ち時間を作るために@Asyncメソッドを使用して生成されます。私は特定のサイズの固定スレッドプールでConcurrentTaskExecutorを使用している場合、これは達成されるのでしょうか?
私は、任意のメッセージを失うことはないとともに、可能なスレッド数を制限したいです。私のこの要件は、既存の回答から満たされていなかったと私はそれを行うための別の方法を発見しました。したがって、その答えとして、それを投稿:
次のように私は執行豆を作りました:
@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(新しいThreadPoolExecutor.CallerRunsPolicy())
私の5つのスレッドが忙しくしているとき、私の呼び出し元のスレッドがタスクを実行します&私の呼び出し元のスレッドが非同期関数内であることから、それはどんな新しいタスクを取らないことを手伝ってくれました。したがって、私は、キューのサイズを大きくすることなく、自分の仕事を失うことはありません。