1

次のことを行うスレッドを調整しようとしています。

スレッドが 1 つだけのスレッド プール[CorePoolSize =0, maxPoolSize = 1]

使用されるキューはArrayBlockingQueue です

Quesize = 20

BackGround:
スレッドは、リクエストを読み取って操作を実行しようとします。

しかし、最終的にはリクエストが非常に増加したため、スレッドは常にビジー状態になり、1 つの CPU を消費してリソースを大量に消費します。

私がやりたいことは、代わりにリクエストを一定間隔でサンプリングして処理することです。他のリクエストは安全に無視できます。

私がしなければならないことは、「操作」機能にスリープを入れて、タスクごとにスレッドがしばらくスリープしてCPUを解放することです。

質問:
ただし、次の要素を読み取る前に、基本的にそれ自体がしばらくスリープするキューを使用する方法があるかどうか疑問に思っていました。実行中にタスクをスリープさせ、実行を未完了のままにしておくのは、私には最適とは思えないため、これは理想的です。

他にもお勧めのタスクがあれば教えてください

ありがとう。

編集:ここにフォローアップの質問を追加し 、maxpool サイズを 1 に修正しました [急いで書いた] ..指摘してくれてありがとう tim。

4

4 に答える 4

1

これはうまくいかないかもしれませんが、エグゼキュータのスレッド優先度を低く設定してみることができます。

基本的に、カスタムThreadFactoryを使用してThreadPoolExecutorを作成します。メソッドがThread.MIN_PRIORITYの優先度を持つスレッドを返すようにします。これにより、使用するエグゼキュータサービスは、実行可能なコアがある場合にのみスケジュールされます。ThreadFactory.newThread()

意味:タイムスライシングを厳密に使用するシステムでは、プログラム全体にスケジュールを要求する優先度の高い他のスレッドがない場合にのみ、実行するタイムスライスが与えられます。アプリケーションが実際にどれだけビジーであるかに応じて、時々スケジュールされる場合と、まったくスケジュールされない場合があります。

于 2010-10-05T22:50:06.577 に答える
1

ThreadPool をサブクラス化し、 beforeExecuteをオーバーライドしてしばらくスリープさせることができます。

@Overrides
protected void beforeExecute(Thread t,
                         Runnable r){
    try{
       Thread.sleep( millis);  // will sleep the correct thread, see JavaDoc
    }
    catch (InterruptedException e){}

  }

しかし、人為的にキューを遅くすることはおそらく良い考えではないというAngerClownのコメントを参照してください。

于 2010-10-05T00:18:58.777 に答える
1

スレッドが 100% の CPU を消費している理由は、処理できる以上の作業がスレッドに与えられているためです。タスク間に遅延を追加しても、この問題は解決されません。それは事態を悪化させるだけです。

代わりに、プロファイラーなどを使用してタスクが大量の CPU を消費している理由を調べ、スレッドが追いつくことができて 100% の CPU を消費しなくなるまで、CPU の消費量が少なくなるようにタスクを変更する必要があります。

于 2010-10-07T19:49:43.857 に答える