2012-03-14 13 views
10

スレッドにメインループがあり、アイドルブール値が真であるかどうかテストします。そうであれば、ループの繰り返しごとにThread.sleep(1)を呼び出します。これをやり遂げるのは効率的な方法ですか?私の目標は、アイドル時にスレッドがCPU使用量を最小限に抑えることです。Javaでは、アイドル状態のスレッドにThread.sleep(1)を使用するのが効率的ですか?

+0

システムがスレッドを常にこのようにスワップするのに時間がかかりませんか?それは、スレッドマネージャがその仕事をするための処理能力を必要とし、ミリ秒ごとにその仕事をするように求めています。 – scriptocalypse

+0

それは私が起こるかもしれないと思われるものの1つですが、私は当時は分かりませんでした。 'wait'のように聞こえ、' notifyAll'は仕事をうまくやってくれます。 – AutoBotAM

答えて

8

いいえ。Object.waitを代わりに使用して、ブール値を含むオブジェクトで同期していることを確認してください。同期しておらず、booleanvolatileでない場合は、メモリバリアがないため、ポーリングスレッドにbooleanへの変更が表示されるという保証はありません。 javadocによると

このメソッドは、このオブジェクトの待機セットに自身を配置すると、このオブジェクト上の任意およびすべての同期の請求を放棄する(Tそれを呼び出す)現在のスレッドが発生します。 スレッドTは、スレッドのスケジューリングに関して無効になり、4つのいずれかが起きるまで待機します。

  • 他のスレッドがこのオブジェクトのnotifyメソッドを呼び出し、Tは、スレッドが起こされるよう任意に選択することを起こるスレッド。
  • 他のスレッドは、このオブジェクトに対してnotifyAllメソッドを呼び出します。
  • 他のスレッドがスレッドT.
  • を中断...

通知されるのを待っている間、そのスレッドにはCPUを負いません。

以下のコードは、あなたのmainメソッドが呼び出すことができwaitUntilIdle方法と別のスレッドで呼び出すことができsetIdle方法と簡単なアイドルフラグです。

public class IdleFlag { 
    private boolean idle; 

    public void waitUntilIdle() throws InterruptedException { 
    synchronized (this) { 
     while (true) { 
     // If the flag is set, we're done. 
     if (this.idle) { break; } 
     // Go to sleep until another thread notifies us. 
     this.wait(); 
     } 
    } 
    } 

    public void setIdle() { 
    synchronized (this) { 
     this.idle = true; 
     // Causes all waiters to wake up. 
     this.notifyAll(); 
    } 
    } 
} 
+0

これはうまくいくものですが、同期外のwhile(true)の理由は何ですか?それはちょうどロックを解放し、待ってから再獲得することになります。シンク内に 'while(true)'を持つことに加えて、待機が通知されるたびに(定期的にまたは偽りに)セマンティクスを取得/解放します(1回のみ)。 –

+1

私の主張は、あなたが余分なリリースを受けることのないシンク内では簡単に「中」できることです。あなたは正常ですが、機能上の害はなく、パフォーマンスへの影響はごくわずかです。 –

+0

@JohnVint、良い点。編集されました。 –

1

私は@マイクサミュエルに同意し、まだ私はちょうど5

具体的には、Javaで導入されたもので、彼のロックを置き換えるマイクのパラダイムであなたがconcurrent lock packages...

続行使用することをお勧めしたいと思いますCondition'sメソッドを待つことができます - タイムアウトをとるメソッド。そうすることで、例えば、非常に頻繁にメッセージを記録することができます。これは、無限の待機をデバッグするのに役立つメッセージです。タイムアウトを待っている場合は、ロールバックロジックを実行することもできます。

+0

タイムアウトが発生するバージョンの 'wait'があります。したがって、' wait(timeout) 'コールを使うと、' Condition'sを導入するよりも簡単にCPU時間を取得したいだけです。 –

+0

@ジョンHaager - 洞察力のおかげで、私はそれを認識していなかったと言って恥ずかしいです – Yaneeve

+0

まだ条件はロックに関連しており、彼らは単純な同期よりも面白いことをすることができます – Yaneeve

関連する問題