質問

java.util.concurrent.blockingqueueから要素を引き出して処理しているタスクがあるとします。

public void scheduleTask(int delay, TimeUnit timeUnit)
{
    scheduledExecutorService.scheduleWithFixedDelay(new Task(queue), 0, delay, timeUnit);
}

周波数を動的に変更できる場合、タスクをスケジュール /再スケジュールするにはどうすればよいですか?

  • アイデアは、データの更新のストリームを取得し、それらをバッチでGUIに伝播することです
  • ユーザーは更新の頻度を変えることができるはずです
役に立ちましたか?

解決

固定レート遅延を変更できるとは思いません。使用する必要があると思います スケジュール() ワンショットを実行し、1回完了したら再度スケジュールします(必要に応じて変更されたタイムアウトを変更します)。

他のヒント

使用する schedule(Callable<V>, long, TimeUnit) それよりも scheduleAtFixedRate また scheduleWithFixedDelay. 。次に、あなたの呼び出しが可能であることを確認します 再スケジュール自体または新しい呼び出し可能なインスタンス 将来のある時点で。例えば:

// 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);

このアプローチは、シャットダウンして再作成する必要性を回避します ScheduledExecutorService.

使用してはいけません scheduleAtFixedRate 特定の間隔でいくつかのキュータスクを処理しようとしている場合は? scheduleWithFixedDelay 指定された遅延が待機してから、キューから1つのタスクを実行します。

どちらの場合でも、 schedule* aの方法 ScheduledExecutorService 返品します ScheduledFuture 参照。レートを変更したい場合は、 ScheduledFuture 異なるレートでタスクを再スケジュールします。

schedulewithfixeddelay(...)runnableScheduledfutureを返します。それを再スケジュールするために、あなたはそれをキャンセルして再スケジュールするだけです。それを再スケジュールするために、あなたは単にrunnableScheduledfutureを新しい実行可能にするために包むことができます:

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

私は最近、ScheduledFutureを使用してこれをしなければなりませんでしたが、Runnableなどをラップしたくありませんでした。これが私がそれをした方法です:

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);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top