2009-10-05 11 views
12

java.util.concurrent.BlockingQueueから要素を引き出して処理するタスクがあるとします。可変遅延付きScheduledExecutorService

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

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

  • アイデアは、ユーザーがアップデート
+0

なぜブロックキューを使用しているのかはわかりません。 キューが空の場合。あなたの予定された仕事がブロックされると思います。それはあなたの意図ですか?タスクスケジューラのタイミングが混乱する可能性があります。 –

+0

ArrayBlockingQueue実装は、スレッドセーフである必要があり、FIFOの順序付けを尊重し、バインドする必要があるため、実装を選択しました。タスクがブロックされても、タスクスケジューリングを混乱させるべきではありませんか? – parkr

+0

BlockingQueue実装を使用するのは正しいです(実際にはScheduledThreadPoolExecutorは内部で1つを使用します)。しかし、なぜタイマーを使って更新をGUIに伝えているのですか?なぜそれをリアルタイムでしないのですか?更新が多すぎますか?スイングスレッドが回転しているのを心配していますか? – Adamski

答えて

6

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

+1

ありがとうございました - 私はインスタンス変数を「遅延」させ、以下を行うプライベートメソッドを追加しました:while(!executorService.isShutdown){executorService.schedule(new Task(queue)、delay、TimeUnit.MILLISECONDS); } – parkr

1

の周波数を変化させることができるはずのデータ更新の流れを取り、GUI

  • に一括でそれらを伝播することであるあなたが使用してはいけません特定の間隔で複数のキュータスクを処理しようとしている場合はscheduleAtFixedRatescheduleWithFixedDelayは、指定された遅延を待ってから、キューから1つのタスクを実行します。いずれの場合でも、ScheduledExecutorServiceschedule*の方法は、ScheduledFutureの参照を返す。レートを変更する場合は、ScheduledFutureをキャンセルして、異なるレートでタスクを再スケジュールすることができます。

  • +0

    scheduleWithFixedDelay(...) - 与えられた初期遅延の後に最初に有効になり、続いて1つの実行の終了と次の実行の開始の間の所定の遅延で有効になる定期的アクションを作成して実行します。タスクの実行によって例外が発生すると、後続の実行は抑制されます。それ以外の場合、タスクはエグゼキュータのキャンセルまたは終了によってのみ終了します。 – parkr

    +0

    キャンセルや再スケジュールのコード例を挙げられますか?進行中のアップデートはどうですか? – parkr

    0

    scheduleWithFixedDelay(...)は、RunnableScheduledFutureを返します。再スケジュールするには、キャンセルして再スケジュールするだけです。むしろscheduleAtFixedRateまたはscheduleWithFixedDelayより

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

    使用schedule(Callable<V>, long, TimeUnit):それを再スケジュールするには、あなただけのRunnableScheduledFutureウィット新しいRunnableをを包むことがあります。次に、Callable が今後予定されているか、または新しいCallableインスタンスが将来予定されていることを確認してください。たとえば:

    // 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を再作成する必要がありません。

    +0

    'Callable 'の代わりに 'Runnable'を使うことができますか? – Thirler

    +0

    @Thirler:はい、それは公正な点です。 – Adamski

    +0

    ScheduledExecutorServiceの 'schedule(Callable)'関数が見つかりません。すべてのパラメータを持つもののみ。私をどこに指摘していただけますか?または、少なくとも0の遅延を含めるように例を修正しました。 – jlanza