abksrv
abksrv

Reputation: 1405

Run a ScheduledExecutorService periodically or just once based on condition

I have a specific task which has to be executed periodically, or just once based on a condition. I am using the following approach:

Runnable r = new Runnable() {

        public void run() 
        {       
            //Execute task
        }
    };
final long freq = frequencyOfTask;
ScheduledExecutorService dataTimer = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> dataTimerHandle = dataTimer.scheduleAtFixedRate(r, 0L, freq, TimeUnit.MILLISECONDS);
if(!isDynamic)
{
    dataTimerHandle.cancel(false); //cancel the event in main thread while asking the already submitted tasks to complete.
}

The task runs fine for the case where isDynamic is false, i.e., where the task is not cancelled. But, for the other case (when the execution is required just once) it doesn't execute at all.

Upvotes: 0

Views: 2690

Answers (1)

skaffman
skaffman

Reputation: 403441

It doesn't execute because you're cancelling the task before it has a chance to run even once - scheduleAtFixedRate will return immediately and allow your method to continue executing, and the first thing it does is to cancel the as-yet-unexecuted task.

Instead of scheduling the task and then cancelling it, just submit it as a non-scheduled task instead, e.g.

ScheduledExecutorService dataTimer = Executors.newScheduledThreadPool(1);

if(isDynamic)
{
    dataTimer.scheduleAtFixedRate(r, 0L, freq, TimeUnit.MILLISECONDS);
}
else
{
    dataTimer.submit(r);
}

In the latter case, the task will execute just once.

Upvotes: 4

Related Questions