[ACCEPTED]-ScheduledExecutorService with variable delay-blockingqueue

Accepted answer
Score: 34

Use schedule(Callable<V>, long, TimeUnit) rather than scheduleAtFixedRate or scheduleWithFixedDelay. Then ensure that 3 your Callable reschedules itself or a new Callable instance at some point in the future. For 2 example:

// Create Callable instance to schedule.
Callable<Void> c = new Callable<Void>() {
  public Void call() {
   try { 
     // Do work.
   } finally {
     // Reschedule in new Callable, typically with a delay based on the result
     // of this Callable.  In this example the Callable is stateless so we
     // simply reschedule passing a reference to this.
     service.schedule(this, 5000L, TimeUnit.MILLISECONDS);
   }  
   return null;
  }
}

service.schedule(c);

This approach avoids the need to 1 shut down and recreate the ScheduledExecutorService.

Score: 8

I don't think you can change a fixed rate 4 delay. I think you need to use schedule() to perform 3 a one-shot, and schedule again once that 2 has completed (with a modified time out 1 if required).

Score: 5

I had to do this recently using ScheduledFuture 2 and didn't want to wrap Runnable or such. Here's 1 how I did it:

private ScheduledExecutorService scheduleExecutor;
private ScheduledFuture<?> scheduleManager;
private Runnable timeTask;

public void changeScheduleTime(int timeSeconds){
    //change to hourly update
    if (scheduleManager!= null)
    {
        scheduleManager.cancel(true);
    }
    scheduleManager = scheduleExecutor.scheduleAtFixedRate(timeTask, timeSeconds, timeSeconds, TimeUnit.SECONDS);
}

public void someInitMethod() {

    scheduleExecutor = Executors.newScheduledThreadPool(1);    
    timeTask = new Runnable() {
        public void run() {
            //task code here
            //then check if we need to update task time
            if(checkBoxHour.isChecked()){
                changeScheduleTime(3600);
            }
        }
    };

    //instantiate with default time
    scheduleManager = scheduleExecutor.scheduleAtFixedRate(timeTask, 60, 60, TimeUnit.SECONDS);
}
Score: 2

Shouldn't you be using scheduleAtFixedRate if you are trying 7 to process several queue tasks with a specific 6 interval? scheduleWithFixedDelay will only wait for the specified 5 delay and then execute one task from the 4 queue.

In either case, the schedule* methods in a 3 ScheduledExecutorService will return a ScheduledFuture reference. If you want to 2 change the rate, you can cancel the ScheduledFuture and 1 reschedule the task with a different rate.

Score: 0

scheduleWithFixedDelay(...) returns a RunnableScheduledFuture. In 4 order to reschedule it, you might just cancel 3 and reschedule it. To reschedule it, you 2 may just wrap the RunnableScheduledFuture 1 wit a new Runnable:

new Runnable() {
    public void run() {
        ((RunnableScheduledFuture)future).run();
    }
};

More Related questions