25

java.util.concurrent.BlockingQueue から要素を取得して処理するタスクがあるとします。

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

頻度を動的に変更できる場合、タスクをスケジュールまたは再スケジュールするにはどうすればよいですか?

  • アイデアは、データ更新のストリームを取得し、それらをバッチで GUI に伝達することです。
  • ユーザーは更新の頻度を変更できる必要があります
4

5 に答える 5

33

またはのschedule(Callable<V>, long, TimeUnit)代わりに使用します。次に、 Callableが将来のある時点でそれ自体または新しい Callable インスタンスを再スケジュールするようにします。例えば:scheduleAtFixedRatescheduleWithFixedDelay

// 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ます。

于 2009-10-05T10:31:05.027 に答える
7

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

于 2009-10-05T09:58:20.377 に答える
2

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

いずれの場合も、schedule*a のメソッドは参照ScheduledExecutorServiceを返しScheduledFutureます。レートを変更する場合は、 をキャンセルし ScheduledFutureて、別のレートでタスクを再スケジュールできます。

于 2009-10-05T09:56:37.557 に答える
0

scheduleWithFixedDelay(...) は RunnableScheduledFuture を返します。再スケジュールするには、キャンセルして再スケジュールするだけです。再スケジュールするには、RunnableScheduledFuture を新しい Runnable でラップするだけです。

new Runnable() {
    public void run() {
        ((RunnableScheduledFuture)future).run();
    }
};
于 2009-10-05T10:00:26.930 に答える