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您也可以使用无界队列,它是队列大小参数的默认值,但要小心,因为如果队列中堆积了太多任务 ,可能会导致这种情况。
添加回答
举报
