Why does ScheduledExecutorService.schedule(Runnable r, Long delay, TimeUnit t) ignore the delay and runs instantly?

StackOverflow https://stackoverflow.com/questions/19804192

  •  04-07-2022
  •  | 
  •  

Question

I have a ScheduledExecutorService that I want to use to schedule the execution of a Runnable with a certain delay. However, when I call its schedule method the delay is completely ignored and the Runnable is executed instantly. This is my code:

My ScheduledExecutorService constructor:

    private static ScheduledExecutorService existQueuePool = Executors.newScheduledThreadPool(1);

and this is the call to its schedule method (surrounded by Logs):

Log.d(TAG,"Before schedule");
ScheduledFuture<?> mScheduledFuture = existQueuePool.schedule(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG,"Setting clearMessageTask for exist messages in the existQueuePool.");                       
                        clearMessageTask(mContext.getString(R.string.existType));
                    }
                }, 1000L, TimeUnit.MILLISECONDS);
Log.d(TAG,"After schedule");

The logs allow me to see that there's only a 20-30ms delay between the "Before schedule" and the "Setting clear...", instead of 1000ms as I was expecting.

The documentation on the schedule method reads:

Creates and executes a one-shot action that becomes enabled after the given delay.

What does the term "enable" exactly mean in this context?

Any help will be greatly appreciated.

EDIT: Even when using a Long (1000L), the code seems to execute immediately.

Was it helpful?

Solution

I think you have it right. Try 1000L, as a long value is expected, instead of an int.

Edit: Tried it myself, and your code works for me:

package testdelay;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class TestDelay {

    private static final ScheduledExecutorService existQueuePool = Executors.newScheduledThreadPool(1);
    private static long start;
    private static long end;
    public static void main(String[] args) {
        start = System.currentTimeMillis();
        System.out.println("Before execution: " + start);
        ScheduledFuture<?> mScheduledFuture = existQueuePool.schedule(new Runnable() {
                    @Override
                    public void run() {
                        end = System.currentTimeMillis();
                        System.out.println("Executed at: " + end);
                        System.out.println("Executed after delay of : " + (end - start) + " ms.");
                    }
                }, 1000L, TimeUnit.MILLISECONDS);
    }
}

Output:

Before execution: 1386350613147
Executed at: 1386350614149
Executed after delay of : 1002 ms.

It appears that it runs instantaneously because you log a message outside of the runnable, which is executed right after the submission to the service. You should log it in the runnable itself to see when it is ran.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top