Thread.sleep within @Scheduled method in Spring

Thread.sleep within @Scheduled method in Spring

spring scheduler run once
spring scheduler cron expression from database
scheduled(fixedrate)
spring boot scheduler multiple threads
spring scheduled private method
thread.sleep in java for 1 minute
spring boot scheduler example mkyong
delay in java without using thread

I have a method that is scheduled to run each X ms.

This method is launching a new method within a new thread.

Nevertheless, I want to delay this method before counting again.

Here is my code:

@Scheduled(fixedRate = RATE_IN_MS)
public void myMethod(){
    new Thread(() -> method()).start();
    Thread.sleep(RATE_IN_MS);
}

The problem is that the behavior is not like I want.

Here is the current behavior:

  1. After RATE_IN_MS myMethod is launched.
  2. method() start running in a different thread.
  3. After RATE_IN_MS myMethod is launched.

The problem: Why does my sleep method didn't delay the next launch of myMethod? RATE_IN_MS (by fixedDelay) + RATE_IN_MS (because of Thread.sleep(RATE_IN_MS) need to be the real delay between them.

What I'm missing here?

Thanks!


With fixedRate, the scheduler does not care the time spent in myMethod.

You can use @Scheduled(fixedDelay = RATE_IN_MS). The scheduler will calculate next execution time after finishing myMethod.

How to Delay Code Execution in Java, Learn different ways to implement delays in Java. It is good practice to wrap the sleep method in a try/catch block in case used inside of loops, sleep will drift slightly between loop iterations due to other code This interface can schedule code to run once after a specified delay or at fixed time intervals. Spring provides excellent support for both task scheduling and asynchronous method execution based on cron expression using @Scheduled annotation. The @Scheduled annotation can be added to a method along with trigger metadata. In this post, I will show the means to use @Scheduled feature in 4 different ways. Read More : Spring timer tasks Table …


I have created this running example for your reference.Execution delay is configured in spring configuration file which can be changed as you wish.

package com.myprgm;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

@Component
@EnableScheduling
public class JobSchdulingServc {
    @Value("${com.executionDelay}")
    private long executionDelay; // in milliseconds,mention in sping property file
    @Autowired
    TaskScheduler taskScheduler;

    @Bean
    public TaskScheduler poolScheduler() {
        return new ThreadPoolTaskScheduler();
    }

    private void stopSceduling(boolean terminateJob) {
        ((ThreadPoolTaskScheduler) taskScheduler).shutdown();
        if (terminateJob) {
            System.exit(1);
        }

    }
    public void scheduleMyJob() {
        taskScheduler.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                try {
                    someServiceimpl.generateMyDataAndSendInEveryMilliSeconds(); // service you want to execute after
                    // specified executionDelay
                } catch (Exception e) {
                    stopSceduling(true);
                }
            }

        }, executionDelay);
    }

}

27. Task Execution and Scheduling, Spring's TaskExecutor interface is identical to the java.util.concurrent. All of the other methods are capable of scheduling tasks to run repeatedly. value provided for the 'id' attribute will be used as the prefix for thread names within the pool. the number of milliseconds to wait after each task execution has completed. @Scheduled method arguments and return value. The methods annotated with @Scheduled must have void returns and must not have any arguments. This is because of it's periodic nature where passing an argument or receiving a return value won't make much sense. Following example shows that violating this rules will end up with an exception.


When using fixedrate scheduling, there are two possible situations as to when the next invocation of myMethod occurs:

  1. if after RATE_IN_MS milliseconds from the last myMethod invocation, myMethod is no longer running, then that's when myMethod will be invoked again.
  2. if after RATE_IN_MS milliseconds from the last myMethod invocation that invocation is still running and it hasn't returned, then this will cause the next scheduled call to be blocked until the current invocation is over.

For example if RATE_IN_MS is 10 ms, let's consider two scenarios:

  1. myMethod takes 5 ms to execute. In this case, a new myMethod invocation will occur every 10 ms because 5 ms is less than 10 ms.
  2. if for some reason the last myMethod invocation took 12 ms to complete, which is longer than 10 ms, then the next one will be queued. So there will be a minimum of 12 ms between invocation which is more than RATE_IN_MS.

Now to answer your question specifically, let's say that RATE_IN_MS is 10 ms, then definitely we have the second case from my above example, however, the wait time will not be multiplied in two as you expect, rather it will be consisted of two time periods:

  1. the time it took myMethod to reach Thread.sleep(RATE_IN_MS) which could be much less than RATE_IN_MS, let's say it's only 3 ms and let's call this time X.
  2. the time the Thread sleeps which is RATE_IN_MS which we are saying it's 10 ms for example.

Then the total time between invocations of myMethod() will be: X+RATE_IN_MS which according to my example is 13 ms and not RATE_IN_MS * 2.

Spring - Task Scheduling using @Scheduled, Spring provides annotation support for scheduling method execution using getName(), LocalTime.now()); try { Thread.sleep(500); } catch  We can run a scheduled task using Spring's @Scheduled annotation but based on the properties fixedDelay and fixedRate the nature of execution changes. The fixedDelay property makes sure that there is a delay of n millisecond between the finish time of an execution of a task and the start time of the next execution of the task.


How to Schedule Tasks with Spring Boot, In this article, you'll learn how to schedule tasks in Spring Boot using the You'll also configure a custom thread pool for executing all the scheduled tasks. The @Scheduled annotation is added to a method along with some called ScheduledTasks inside com.example.schedulerdemo package with the  In this tutorial, we showed some approaches to test scheduled tasks using integration testing and the Awaitility library. We need to take into account that, although integration tests are good, it's generally better to focus on the unit testing of the logic inside the scheduled method.


Spring @Scheduled - 4 Ways to Schedule Tasks, If you want the external objects to be used within your @Scheduled methods, you should DemoServiceBasicUsageFixedDelay.java Thread.sleep( 12000 );. The most powerful feature of Spring's task namespace is the support for configuring tasks to be scheduled within a Spring Application Context. This follows an approach similar to other "method-invokers" in Spring, such as that provided by the JMS namespace for configuring Message-driven POJOs.


Scheduling Spring Boot Tasks, In this article, we'll explore the scheduling capabilities of Spring Boot. To schedule a method to execute on a fixed rate, we'll add the adequate parameter to our currentThread()); Thread.sleep(1000); logger.info("Task 1 ends" + Thread. Methods annotated with @Scheduled may even be declared directly within @Configuration classes: @Configuration @EnableScheduling public class AppConfig { @Scheduled(fixedRate=1000) public void work() { // task execution logic } }