9

我有一个任务安排如下:

<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>

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

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

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

4

2 回答 2

6

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

甚至核心线程最初都是在新任务到达时才创建和启动的

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

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

于 2012-04-20T19:14:08.337 回答
4

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

corePoolSize - 保留在池中的线​​程数,即使它们是空闲的。

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

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

于 2012-04-20T18:23:40.257 回答