java 为什么spring任务调度器会等待上一个任务完成?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13197904/
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 11:50:39  来源:igfitidea点击:

Why does spring task scheduler wait for previous task to finish?

javaspring

提问by GuerillaNerd

I have the following task scheduler setup:

我有以下任务调度程序设置:

<bean id="Task" class="foo.bar.Task" />

<bean id="TaskScheduler"
  class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
    <property name="waitForTasksToCompleteOnShutdown" value="true" />
    <property name="poolSize" value="1000" />
</bean>

<task:scheduled-tasks scheduler="TaskScheduler">
  <task:scheduled ref="Task" method="run" cron="*/5 * * * * *" />
</task:scheduled-tasks>

The Task just prints a line and sleeps for 10 seconds. With this setup, my expectation was that the task would run every 5 seconds, regardless of whether the previous task had finished it's execution (ie stopped sleeping). But that's not the case, the task runs once ever 15 seconds (the sleep time and then the next time the cron is hit).

任务只打印一行并休眠 10 秒。有了这个设置,我的期望是任务将每 5 秒运行一次,无论前一个任务是否已完成执行(即停止睡眠)。但事实并非如此,该任务每 15 秒运行一次(睡眠时间,然后是下次命中 cron 时)。

How can I configure this so that the task runs every 5 seconds regardless of whether the previous execution finished?

如何配置它以便任务每 5 秒运行一次,而不管上一次执行是否完成?

回答by someone

In you run method put @Async anotation and see

在您运行方法中放置@Async 注释并查看

   @Async
   public void run{

   }

or you can

或者你可以

Try out this

试试这个

<bean id="schedulerTask"
       class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
    <property name="mytaskClass" ref="mytaskClass" />
    <property name="targetMethod" value="fooMethod" />
</bean>

<bean id="mytaskClass" class="foo.bar.Task" />

<bean id="timerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
    <property name="timerTask" ref="schedulerTask" />
    <property name="delay" value="10" />
    <property name="period" value="5000" />
</bean>

<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
    <property name="scheduledTimerTasks">
        <list>
            <ref local="timerTask" />
        </list>
    </property>
</bean>

Then Your class

那么你的课

 package foo.bar;

 public class Task{

  public void fooMethod(){
  // do task
 }

}

Added as per the request

根据要求添加

   <!-- Thread pool related configurations  -->
   <bean name="workerThread" class="foo.WorkerThread"/>

  <bean name="managerThread" class="foo.ManagerThread" >
     <constructor-arg type="org.springframework.core.task.TaskExecutor" ref="taskExecutor" />
     <constructor-arg type="foo.process.WorkerThread" ref="workerThread"/>
   </bean>

   <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
 <property name="corePoolSize" value="5" />
 <property name="maxPoolSize" value="30" />
 <property name="queueCapacity" value="100" />
</bean>
<!-- End Thread pool related configurations  -->

ManagerThread.java

线程管理器

public class ManagerThread {

private  TaskExecutor taskExecutor=null;
private  WorkerThread workerThread=null;


/**
 * @param taskExecutor
 * @param workerThread
 */
public ManagerThread(final TaskExecutor taskExecutor,final WorkerThread workerThread) {

    this.taskExecutor = taskExecutor;
    this.workerThread = workerThread;
}  


/**
 * Create a new thread and execte the requests
 * @param parameter
 */
 public synchronized void  fire(final Object parameter) {
    taskExecutor.execute( new Runnable() {
         public void run() {
             workerThread.execute( parameter );
         }
    });
  }

WorkerThread.java

工作线程.java

@Component
public class WorkerThread {




public void execute(final Object request) {

     // do the job
    }

}

You could customize this as per your requirement

您可以根据您的要求定制它

回答by Jeevan Patil

You can increase thread pool size to allow multiple cron jobs to run simultaneously.

您可以增加线程池大小以允许多个 cron 作业同时运行。

<task:scheduler id="taskScheduler" pool-size="10"/>