ScheduledExecutorService with variable delay

前端 未结 5 1969
别那么骄傲
别那么骄傲 2020-12-09 03:44

Suppose I have a task that is pulling elements from a java.util.concurrent.BlockingQueue and processing them.

public void scheduleTask(int delay, TimeUnit ti         


        
相关标签:
5条回答
  • 2020-12-09 03:55

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

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

    0 讨论(0)
  • 2020-12-09 03:59

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

    0 讨论(0)
  • 2020-12-09 04:05

    I had to do this recently using ScheduledFuture and didn't want to wrap Runnable or such. Here's 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);
    }
    
    0 讨论(0)
  • 2020-12-09 04:17

    Use schedule(Callable<V>, long, TimeUnit) rather than scheduleAtFixedRate or scheduleWithFixedDelay. Then ensure that your Callable reschedules itself or a new Callable instance at some point in the future. For 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 shut down and recreate the ScheduledExecutorService.

    0 讨论(0)
  • 2020-12-09 04:18

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

    new Runnable() {
        public void run() {
            ((RunnableScheduledFuture)future).run();
        }
    };
    
    0 讨论(0)
提交回复
热议问题