0

LinkedBlockingQueue呼び出してtasksいますが、呼び出しtasks.take()てタスクが使用可能になるのを待つと、CPU 使用率が 100% になります。メソッドを使用する複数のスレッドtasks.take()があります (すべてのスレッドには独自のtasks変数があります)。なぜこれが起こっているのか誰にも分かりますか?

tasks変数の定義

private LinkedBlockingQueue<ComputerTask> tasks;
// snip
this.tasks = new LinkedBlockingQueue<ComputerTask>(100);

タスクを取るコード

ComputerTask task = tasks.take();

新しいタスクを提供するコード

this.tasks.offer(task);

PSこれが私のバージョンのJavaに問題があるかどうかはわかりません。他のコンピューターではまだテストしていないためです。

java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04-413-11M3623)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01-413, mixed mode)
4

1 に答える 1

3

呼び出されたタスクがありますが、LinkedBlockingQueue呼び出しtasks.take()てタスクが使用可能になるのを待つと、CPU 使用率が 100% になります。メソッドを使用する複数のスレッドtasks.take()があります (すべてのスレッドには独自のタスク変数があります)。

tasks.take();多数のアイテムをデキューしていない限り、回転しないでください。キューが空の場合はブロックされるため、これが100% の負荷の原因ではないと思われます。プロファイラーを使用するか、周りにデバッグステートメントを追加してtake()、何度も呼び出されているかどうかを確認してください。

覚えておくべきことの 1 つは、キューがいっぱいになるとすぐにtasks.offer(task)戻ることです。代わりにブロックし、スピンしないfalseものを使用する必要があると思います。タスクを実行するタスク ハンドラを決定するために をtasks.put(task)使用している場合、すべてのタスク ハンドラのキューがいっぱいになるとループを繰り返しているのではないでしょうか?offer()

独自のタスク管理を行っている場合は、代わりに組み込みExecutorServiceクラスの 1 つを使用することを検討してください。次に、すべてのタスクを送信するか、ブロッキング キューを使用ExecutorServiceして、プール内の各スレッドにそのタスクを供給することを処理します。

// start 10 threads handling the tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// now submit tasks to the pools that will be run with the 10 threads
threadPool.submit(task);
...

上記の例でComputerTaskは、実装する必要がありますRunnable

于 2012-05-07T16:02:07.043 に答える