2

我在具有@Scheduled 注释的类中有一个方法

@Scheduled(cron = "* * * * * *")
public void doSomething() {

}

这应该每秒执行一次(假设 cron 语句是正确的)。

我将 sping 配置设置为

<task:scheduler id="taskScheduler" pool-size="2" />
<task:executor id="taskExecutor" pool-size="2" />
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler" />

问题是该方法在最后一次执行完成之前不会再次触发。我期待看到它触发两次(并且可能开始在某个地方填满工作队列)。

如何消除方法调用之间的依赖关系,但仍确保一次只运行 2 个进程。

4

3 回答 3

0

It seems an idea would be to past the actual work to the taskExecutor

@Scheduled(cron = "* * * * * *")
 public void doSomething() {
   this.executor.execute(new Runnable() {...}
 }

then add a rejection policy as *CALLER_RUNS*

<task:scheduler id="taskScheduler" pool-size="1" />
<task:executor id="taskExecutor" pool-size="1"
    queue-capacity="1" rejection-policy="CALLER_RUNS" />
<task:annotation-driven executor="taskExecutor"
    scheduler="taskScheduler" />

So with above, the work is always done by one thread pool.

not sure if this is the best way thou.

于 2013-02-22T17:41:11.200 回答
0

由于调度程序线程正忙于运行您的任务,因此不会触发新的执行。

为了实现您要求的行为是将任务委托给执行线程。最简单的方法是简单地使用 @Async 注释该方法。

@Scheduled(cron = "* * * * * *")
@Async
public void doSomething() {
   ...
}

但请记住,您必须将任务执行器池大小调整到所需的容量,以便容纳足够的并行运行的执行器线程。

于 2016-02-26T20:42:43.723 回答
-1

您可以尝试使用@Scheduledwith fixedRate-value 而不是cronor fixedDelay

fixedRate 在调用之间以固定的时间间隔执行带注释的方法。

fixedDelay 在最后一次调用结束和下一次调用开始之间的固定时间段内执行带注释的方法。

使用fixedRate ,该方法的另一次执行被安排在最后一次任务开始之后的一定时间发生。

使用fixedDelay时,下一次调用会在最后一次任务结束之后的一定时间发生。

自然,您的线程池必须有另一个空闲线程才能按时运行任务(如果前一个仍在执行)。

于 2013-02-23T10:17:19.443 回答