2012-05-07 20 views
0

tasksというLinkedBlockingQueueがありますが、tasks.take()と呼び出してタスクが利用可能になるまで待つと、CPU使用率は100%になります。私は(すべてのスレッドが独自のtasks変数を持っている)tasks.take()メソッドを使用して複数のスレッドを持っています。誰がなぜこれが起こっているのか知っていますか?新しいタスクに巨大なCPUインパクトLinkedBlockingQueue

this.tasks.offer(task); 
を提供するタスク

ComputerTask task = tasks.take(); 

コードを取るために、コードtasks変数

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

Defenition

P.S.これが私の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) 
+0

おそらく、はい、何も作業を推進していないとキューが空になりますか?もしそうなら、それは間違いなく、ループしている消費者スレッドです、それは確実に壊れました! –

+0

はい。キューは空です.0.2秒ごとにいっぱいになりません。それが再び満たされるまでに数分かかることがありました。それは問題なのでしょうか?しかし、それはプログラムの重要な部分です、私は本当にそれを取り除くことはできません。どんな勧告? – Robbietjuh

+0

@Robbietjuh CPUが増えた場所をさらに評価することをお勧めします。たとえば、生産者がいなくても、10本の糸をテイクの上に置くだけです。それでもCPUの増加が見える場合は、別の機能を持たずに同じことをする単純なアプリケーションを作成することを証明するために、別の場所に問題があります。標準のJDKを使用していて、単にLBQで 'take'しているのであれば、CPUの使用量はありません。 –

答えて

2

私はコメントに答えをつけるつもりです。それは多数の項目をデキューされていない限り

tasks.take();が回転するべきではありません。キューが空の場合、それはブロックされますので、私は、これは100%負荷のない原因である疑いがあります。私はあなたがプロファイラを使用するか、take()の回りにデバッグ文を追加して、何度か呼び出されているかどうかを確認します。キューがいっぱいの場合は覚えておくべき

ことの一つは、すぐにfalsetasks.offer(task)リターンということです。私はあなたがtasks.put(task)を使用する必要がありますかと思っていますが、代わりにブロックし、回転しません。 offer()を使用してタスクを実行するタスクハンドラを決定する場合は、すべてのタスクハンドラのキューがいっぱいになったときに周りを回り回っている可能性があります。

独自のタスク管理を行っている場合は、代わりにビルトインExecutorServiceクラスのいずれかを使用して検討するかもしれません。次に、あなたのすべてのタスクを提出するか、ブロッキングキューを使用して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); 
... 

上記の例では、ComputerTaskRunnableを実装する必要があります。

+0

ありがとうございます。私はそれを調べます。私が言いたいことの一つは、待ち行列が満杯にならないということです。そうするには十分なタスクがありません。そしてもしそうすれば、深刻なバグが起こっている。 – Robbietjuh

関連する問題