2016-03-30 12 views
0

私はwait/notifyのメリットについていくつか誤解しています。私はプロセッサコアが何も役に立たないことを理解しているので、なぜサイクルが複雑になるのを待っているのではなくブロックコードを通知するのか? 私は、wait/notifyが2つのスレッドが1つのコアだけで実行される場合にプロセッサ時間を奪うことはないことは明らかです。なぜサイクル中に待機/通知するのが好きですか?

+1

あなたが提案しているようにサイクルで待っているのは、あなたが待っていることが無駄であるかどうかを常に確認していることを推測しています。あなたが待っているプロセスが完了するまで、それはあなたに伝えられます。また、状況がより複雑になるにつれ、whileループは複雑さと拡張性の両方で崩壊し始めます。 –

+2

@the_kaba私は、あなたが「待っていることは明らかです/通知するとプロセッサ時間を盗むことはありません。私が付け加えるのは**一つのコアまたはマルチコア**にかかわらず**真実です**。 'wait/notify'は' while(true) 'サイクルに比べてCPUをビジー状態に保つことはありません。 –

+0

コアを走らせないで待っている理由は何ですか?いずれにしても役立つ作業はなく、待機状態のときにコアを使用することはできません。プロセッサーハードウェアの寿命を延ばすことだけですか? –

答えて

2

最も一般的に呼ばれている「サイクルで待機中」「ビジーループ」または「ビジー待機」のように:

while (! condition()) { 
    // do nothing 
} 
workThatDependsOnConditionBeingTrue(); 

これは、他のスレッドやプロセスの非常に失礼ですCPU時間が必要な場合があります(できるだけそのコアから100%の時間がかかります)。だから、他の変形がある:

while (! condition()) { 
    sleepForShortInterval(); 
    // do nothing 
} 
workThatDependsOnConditionBeingTrue(); 

この変形の小さな睡眠は、アプリケーションがリアルタイムでない限り目立たないべき、100msの長い〜、それであっても、劇的にCPUの使用率をドロップします。

実際に条件が真になってからsleepForShortInterval()が終了するまでの間に一般に遅延があることに注意してください。他の人にもっと礼儀正しくなれるようにするためには、あなたはもっと長い睡眠をとってください - 遅れが増えます。これは、通常、リアルタイムシナリオでは受け入れられません。

condition()がチェックしているものが別のスレッドから変更されていると仮定すると、待っているものが終了したらもう一方のスレッドが目を覚ますことになります。よりクリーンなコード、無駄なCPU、および遅延なし。

もちろん、ビジーウェイトを実装する方が速く、quick'n'dirty状況を正当化する可能性があります。

condition()がfalseと同様に、trueに変更することができるマルチスレッドのシナリオでは、あなたがこの時間の正確な時点でその値を変更する他のスレッドを避けるためにwhileworkThatDependsOnConditionBeingTrue()の間、あなたのコードを保護する必要があるだろう、ということに注意してくださいこれはレースコーディングと呼ばれ、事実の後では非常に難しいです。

+0

すぐにお返事ありがとうございます!ちなみに、私は数週間前に並行性に関するいくつかの本を読んできましたが、今はいくつかの練習が必要です。あなたはプロのように見えますが、私が解決しようとする可能性があるいくつかのタスクについてアドバイスできますか? –

+0

良い演習はプログラミングレベルに大きく依存します。長い間、私は[robocode](http://robocode.sourceforge.net/)で楽しい時間を過ごしました。自分自身で[マルチスレッドのボット](http://robocode.sourceforge.net/)を書くようにしてください! – tucuxi

+0

Re、 "...あなたのアプリケーションがリアルタイムでない限り。" 「リアルタイム」を定義する特定の時間スケールはありません。特定の時間枠内に表示する必要がある出力がある場合、アプリケーションは「リアルタイム」です。ウィンドウは、数分(例えば、ハウスサーモスタット)であってもよく、またはマイクロ秒幅(例えば、ソフトウェア定義の無線アプリケーション)であってもよく、またはその間にあるものであってもよい。 –

1

は、私はケースにプロセッサ時間を盗むしません通知/待機することを明確にしていますが、ほとんど

を言って、あなたの質問に答えたと思います。

私が追加することは、1つのコアまたはマルチコアに関係なく真実です。 wait/notifyは、ループまたは定期的なチェックであるwhileと比較して、ビジー状態でCPUを維持しません。

コアを実行しないで待っている理由は何ですか?いずれにしても役立つ作業はなく、待機状態のときにコアを使用することはできません。

あなたは、1つのアプリケーションが1つのスレッドしか実行されていない単一のアプリケーションの観点から見ていると思います。実際には、many threadsが実行され、competing for cpu cyclesがある実際のアプリケーション(Web /アプリケーションサーバーやスタンドアロンなど)から考えることができます。see the advantage of wait/notify.単一のスレッドでもビジー待機をしてCPUサイクルを焼き付けることは間違いありません。

システム上で実行されている単一のアプリケーション/スレッドであっても、常にCPUプロセスを実行しているOSプロセスとそれに関連するプロセスがCPUサイクルを競合します。あなたはアプリケーションがwhile busy-waitをしているので、それらを餓死させたくありません。

あなたは常にあなたを待っている事は無駄である、終了しているとあなたがスリープを使用する場合は、あなただけのに対し、タイミングと推測されているかどうかをチェックされている提案としてサイクルで待機しているゴードンさんのコメント

から引用あなたが待っているプロセスが終了したことを知らせるまで待機する/あなたにアイドル状態であることを知らせる。

+0

すぐにお返事ありがとうございます。私はちょうどスレッド状態に関する何かを逃した。 WAITING 特定のアクションを実行するために別のスレッドが無期限に待機しているスレッドは、この状態です。 待機する前にスレッドが使用していたリソースが解放され、別のスレッド/プロセスで使用される可能性がありますか?この場合、通知直後にコードが実行されることをどのように確認できますか?この場合に特別な優先順位はありますか? –

+0

@the_kaba **スレッドが待っているリソース** - スレッドが 'wait'メソッドを呼び出したオブジェクトとして' resources'を参照している場合は、そうです他のスレッドは同じオブジェクトに対してロックを取得できます。しかし、このスレッドによって開かれた 'file'などのOSリソースを参照している場合、それらはリリースされず、待機スレッドによって保持されます。 **どのようにそのコードが実行されたか** ** - 通知が一度呼ばれると、スケジューラーはそのロックを待っているスレッドの一つを拾うので、そのことを保証することはできません。これがこのロックを待っている唯一のスレッドでない限り。 –

1

一般に、アプリケーションはCPU上で実行されている唯一のアプリケーションではありません。非回転待ちを使用することは、まず、いくつかの有用な仕事をするためにCPUと競合する他のプロセス/スレッドに対する礼儀の行為である。 CPUスケジューラは、あなたのスレッドが有用な何かを行う場合や、偽のフラグで回転する場合には先験的なことを知ることができません。それで、あなたが実行したくないと言っていない限り、それに基づいて自分自身を調整することはできません。なぜなら、あなたがすることは何もないからです。

実際には、ビジー待機はスレッドをスリープ状態にするよりも速いため、通常wait()メソッドはハイブリッドな方法で実装されています。しばらくの間スピンしてから、実際に眠りにつきます。

さらに、ループで待っているだけではありません。まだ回転しているリソースへのアクセスを同期させる必要があります。そうしないと、競争条件の犠牲になります。

さらに簡単なインターフェイスが必要な場合は、CyclicBarrier,CountDownLatchまたはSynchronousQueueを使用することもできます。

関連する問題