java 池大小实际上如何与 Spring 的计划任务配合使用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10251328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:14:37  来源:igfitidea点击:

How does pool size actually work with Spring's scheduled tasks?

javaspringscheduled-tasksthreadpool

提问by AHungerArtist

I have a task scheduled as such:

我有一个这样安排的任务:

<task:scheduler id="notification.scheduler" pool-size="15" />

<task:scheduled-tasks scheduler="notification.scheduler">
    <task:scheduled ref="notificationProcessor" method="sendNextQueueEvent" fixed-rate="500" />
    <task:scheduled ref="notificationProcessor" method="deleteNextCompletedEvent" fixed-rate="60000" />
</task:scheduled-tasks>

I think I have a misunderstanding of how the scheduled tasks work with the pool size. Despite the pool-size being 15, it seems only one thread is being used. For example, if I have fifteen events in the queue, I would think there would be fifteen threads checking every minute to remove an event from the queue. Obviously, this is wrong.

我想我对计划任务如何与池大小一起工作有误解。尽管池大小为 15,但似乎只使用了一个线程。例如,如果队列中有 15 个事件,我认为每分钟会有 15 个线程检查以从队列中删除一个事件。显然,这是错误的。

How can I make it so that there's fifteen threads calling this method for the time interval using Spring's scheduler abstraction?

我如何才能使用 Spring 的调度程序抽象在时间间隔内有 15 个线程调用此方法?

Edit: What I want to accomplish is this: Every half second, I want to check to see if there are queued events to send. When this is done, I want to send a maximum of 15 (if 15 exist). How would I accomplish this using the spring abstractions for the java thread stuff?

编辑:我想要完成的是:每半秒,我想检查一下是否有排队的事件要发送。完成后,我想最多发送 15 个(如果存在 15 个)。我将如何使用 java 线程的 spring 抽象来实现这一点?

回答by Tomasz Nurkiewicz

First of all <task:scheduler/>is a wrapper around ScheduledThreadPoolExecutorextending ThreadPoolExecutor. JavaDoc for the latter says:

首先<task:scheduler/>ScheduledThreadPoolExecutor扩展的包装器ThreadPoolExecutor。后者的 JavaDoc 说:

even core threads are initially created and started only when new tasks arrive

甚至核心线程也只有在新任务到达时才开始创建和启动

Secondly you must understand that scheduled tasks (this is a Java feature, not Spring's) do not run concurrently, even if they take longer time than repeat interval. They simply wait. So you don't have 15 events waiting in the queue, you have 15 executions that are late and wait for that single thread. No need to create another one because next execution has to wait for the previous one to finish. Again, this is how Java scheduling framework works.

其次,您必须了解计划任务(这是 Java 功能,而不是 Spring 的)不会并发运行,即使它们比重复间隔花费的时间更长。他们只是等待。因此,您没有 15 个事件在队列中等待,您有 15 个延迟执行并等待该单个线程。无需创建另一个,因为下一次执行必须等待前一次完成。同样,这就是 Java 调度框架的工作原理。

Of course if you have several different tasks scheduled, more threads will be created.

当然,如果您安排了多个不同的任务,则会创建更多线程。

回答by nobeh

Spring's task:scheduleris by default a bean properties wrapper for java.util.concurrent.ThreadPoolExecutor:

Spring 的task:scheduler默认情况下是一个 bean 属性包装器java.util.concurrent.ThreadPoolExecutor

corePoolSize - the number of threads to keep in the pool, even if they are idle.

corePoolSize - 要保留在池中的线​​程数,即使它们处于空闲状态。

This does not guarantee that the pools-sizeproperty is equivalent to having that number of activethreads. On the other hand, you should note that at any given point in timethere can be only a maximum number of threads equal to processing cores on the machine that you're using; i.e. all other threads will be waiting to switch to RUNNINGmode and continue execution.

这并不能保证该pools-size属性等同于拥有该数量的活动线程。另一方面,您应该注意,在任何给定的时间点,最多只能有与您正在使用的机器上的处理核心数相等的线程数;即所有其他线程将等待切换到RUNNING模式并继续执行。

Also, in Spring's documentation, it mentions that if this is not what you need, you can also take advantage of ConcurrentTaskExecutor.

此外,在 Spring 的文档中,它提到如果这不是您需要的,您也可以利用ConcurrentTaskExecutor.