9

を使用してScheduledExecutorService、固定レートでサービスを呼び出すタスクを実行しています。サービスは、タスクにデータを返す場合があります。タスクはデータをキューに格納します。他のいくつかのスレッドは、キューからアイテムをゆっくりと選択します

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class EverlastingThread implements Runnable {

    private ScheduledExecutorService executorService;
    private int time;
    private TimeUnit timeUnit;
    private BlockingQueue<String> queue = new LinkedBlockingQueue<String>(500);

    public EverlastingThread(ScheduledExecutorService executorService, int time, TimeUnit timeUnit) {
        this.executorService = executorService;
        this.time = time;
        this.timeUnit = timeUnit;
    }

    public void run() {

        // call the service. if Service returns any data put it an the queue
        queue.add("task");
    }

    public void callService() throws Exception {
        // while queue has stuff dont exucute???????????

        executorService.scheduleAtFixedRate(this, 0, time, timeUnit);
    }
}

タスクによって入力されたキューがクリアされるまで、executorService を一時停止するにはどうすればよいですか。

4

2 に答える 2

4

You can do

if(!queue.isEmpty()) return; 

at the start.

If you are usin a ScheduledExecutorService which has a queue, why are you using it to add to another queue. Can you not just use the queue in the service?

于 2011-07-01T08:13:33.350 に答える
3

エグゼキューターがシャットダウンされると、新しいタスクを受け入れなくなり、現在のタスクが終了するのを待ちます。しかし、エグゼキューターを終了したくはありません。一時停止するだけです。

したがって、できることは、タスクで空のキューを処理することです。あなたのタスクは時々実行されるだけなので、何も処理をしていないときの CPU 使用量は 0 に近くなります。これが「if(!queue.isEmpty()) return;」です。ピーター・ローリーの回答から。

次に、ブロッキング キューを使用します。つまり、キューが空のときにキューに入れられた要素を取得するためにメソッド take() を呼び出すと、エグゼキュータ スレッドは何らかの要素がキューに自動的に追加されるまで待機します。

そう:

  • コードが複雑になるとしても、エグゼキューターを一時停止することはできません。
  • ブロッキング キューは、設計上、必要なことを正確に行います。つまり、キューが空の場合にタスクをブロックします。
  • 必要に応じて、定期的なタスクを実行して、キューが空かどうかを確認できます。
  • とにかく、タスクですでにいずれかの方法を使用する必要があります。そうしないと、キューが空のときに NullPointerException が発生します。
于 2011-07-01T08:36:57.580 に答える