2016-10-18 20 views
2

こんにちは、私はかなりJavaに新しいですし、今では私はJavaの同時性になっています。同期メソッドについては少し疑問があります。私は、同期メソッド内でIf elseを使用して同じ結果を得ることができ、待機/通知方法を使用して、アクションを実行する条件が完全に満たされているかどうかを毎回確認しています。待機と待機の同期メソッド(java)

私は同じ結果を得ていますので、If elseのアプローチには長所と短所があります私は、効率が不利になることを納得させる。なぜなら、Ifが常に条件をチェックしているからだ。誰が待っているのかちょうど止まり、通知を待つから。しかし、他の利点や欠点はありますか?

Thx!

+5

比較しようとしているコードを表示できますか? – Joni

+0

これらの概念は矛盾していません。実際には、条件が既に満たされている場合は、待つ前に常に条件をチェックしておく必要があります。そうしないと永遠に待つことになります。一方、条件が満たされない場合、ループを介して正常にポーリングすることは不可能です。これは、条件を変更するときに他のスレッドが適切に 'synchronized'を使用しなかったことを示すためです。重要なポイントは、一時的にモニタを解放し、別のスレッドが待っている状態を変更する 'synchronized'コードを入力できるようにすることです。 – Holger

答えて

1

2つのコンセプトが混在しています。 If-ElseとWait-Notifyはまったく異なります。 2つのスレッドがそれぞれと通信するようにしたい場合は、があります。これは、if-elseが一般的な条件文である間にWait-Notifyが使用される場所です。

2つのスレッドがif-else条件を使用して簡単に通信できるようにすることはできません。あなたは、スレッドをお互いに相互作用させないようにしているように、あなたのコードを書くことができます。

また、望ましくない結果/計算状態につながる可能性があります。遅かれ早かれあなたはホットチックコードを持っています。

0

synchronizedブロックは、コードスレッドを安全にします。より効率的にするには、wait()notify()またはnotifyAll()を使用します。

たとえば、共有リソースがリストの場合、複数のスレッドが共有します。モニタの同期ブロックに入れると、スレッドはコンテキストスイッチ中に常にジャンプしてコードを実行します。リストが空であっても!

wait()は、従ってリラックスし、さらに通知又はnotifyAll()までCPUサイクルの使用を停止するすべてのスレッドを「伝える」ための機構として、モニタ(synchronized(..)内部オブジェクト)に使用されます。上記の例で

synchronized(monitor) { 

    while(list.isEmpty()) 
     monitor.wait(); 
    doSomething(...) 
} 

別のスレッドがコード内の他notify()notifyAll()又はどこかを実行した後に、doSomething()は、リストが空でないだけを実行します。

  • が、以下のコードで

    1. synchronized(monitor) { 
      
          if(!list.isEmpty()) 
           doSomething(...) 
      } 
      

      スレッドが同期ブロックに入って来、3つの可能なシナリオがありますリストは空です:doSomething() wil私は実行されません。

    2. リストは空ではありません:doSomething()が正しく実行されるか、または...
    3. ifの直後でdoSomethingの前にコンテキストスイッチがあり、もう1つのスレッドがすべてのリストのアイテムを取り出した場合、別のコンテキストスイッチアウトスレッドの後に空のリストにdoSomethig()が実行されます。

    したがって、すべてを集計するために、wait/notifyを使用すると、より効率的なコードが保証されます。スレッドは必要ないときには動作しません。

  • +0

    他のスレッドが 'synchronized'を適切に使用している場合、シナリオ3は起こり得ません。これは' synchronized'ブロックのポイントであり、他のスレッドが干渉できないことを保証します。一方、他のスレッドが 'synchronized'を正しく使用できない場合、' if'と 'while'の間に根本的な違いはないので、ループベースのコードも壊します。どちらの場合でも、 'doSomething(...)'は 'isEmpty()'チェックの後ろにあり、 'synchronized'に依存して中間の変更を防ぎます。 – Holger

    +0

    あなたはそうです、私は別の可能なアイデアを強調したかっただけです。また、Whileは指定されたリンクの文書に従っています。 –

    関連する問題