2011-02-22 21 views

答えて

14

「より良い」は、状況によって異なります。 James McParlaneによれば、彼らは「同等に強力」である。私は、his blog for a discussion on the differencesを見ることを強く勧めます。ここで

は、私が見つけたクイックガイドです:

セマフォ

  • は常にブロックされませんプログラムの任意の場所で使用することができますが、モニター
  • Wait()に使用すべきではありません(すなわち、セマフォカウンタがゼロより大きい場合)。
  • Signal()は、ブロックされたスレッドが存在する場合はそれを解放するか、セマフォカウンタを増加させます。
  • Signal()がブロックされたスレッドを解放する場合、呼び出し元と解放されたスレッドは両方とも継続します。

条件変数

  • はモニター
  • Wait()常にブロック呼び出し側で使用することができます。
  • Signal()は、ブロックされたスレッドが存在する場合はそれを解放するか、シグナルが発生しないかのように失われます。
  • Signal()がブロックされたスレッドを解放する場合、呼び出し元はモニター(Hoareタイプ)を返すか、継続します(Mesaタイプ)。呼び出し元または解放されたスレッドのいずれか一方のみ続行できますが、両方は続行できません。

この情報:http://www.cs.mtu.edu/~shene/NSF-3/e-Book/MONITOR/sema-vs-monitor.html

いくつかの有用なリソース:すべての

+3

これは一般的に面白いですが、Javaに直接的には適用できないため、少し混乱します。ホアレとメサはそれを監視する? – Air

+0

はい、その質問はJavaに求められましたが、答えはJavaに関連していません。 – t0r0X

1

まず、あなたは肝炎どのJDKを使用しているかを決定します。 最初のJavaはスレッドのみを提供します。 Java Tiger(5.0)以降、並行性を処理するための新しいクラスが導入されました。 特に、完全なパッケージが提供されている。java.util.concurrent

私の経験では、コードをもっときれいにするため、モニターが優れていることがわかりました。また、それらを使用すると、コードをもっと分かりやすくします。JDKによって提供される最も有名な実装が特定書き込みを提供する一般的なロックを定義ReentrantLockのクラス、およびReentrantReadWriteLockクラスである:それらは、一般ロックインタフェースを実装するクラスを介して実装されていますおよび/またはreadロック。

これまで、共有オブジェクト(オブジェクトのリストなど)へのアクセスを有効/無効にするためにロックが使用されています。

セマフォ物体座標とのスレッドを制御するために使用される同期され(セマフォCyclicBarrierをたCountDownLatch、及び交換クラスと同様、最新のJDKに設けられた多くのシンクロナイザがあります)。 たとえば、セマフォを使用すると、固定数のトークンをスレッドプールに解放して、同時に実行できる操作の量を決めることができます。個人的には、FuturesとLocksを持つスレッドプールを使用すると、よりクリーンで安全な方法で同じ結果につながるので、私はこのアプローチが嫌いです。

詳細情報は、このマニュアル「Java Concurrency in Practice」およびこのIBMのチュートリアル「Concurrency in JDK 5.0」に記載されています。いくつかのより良い例はhereです。

3

確認するには、モニタは、良い古い​​キーワードを意味します。

最初の質問、あなたのカウンターを持ってロックが必要ですか?

  1. セマフォは、より大きいカウンタを持つことができます。 Nリソースを保護する必要がある場合は、セマフォが最適です。簡単な決定。
  2. 単一のリソースを保護している場合は、セマフォ(1)とモニターが同等に適用できる興味深いケースです。

J2SE 5.0 concurrency articleはここで大きな助言をします。モニターが限られている理由は次のとおりです。

  • すでに保持されているロックを獲得しようとする試みからをオフにバックアップする、または指定した時間待った後放棄し、又は後にロックの試みをキャンセルする方法はありません割り込み。
  • リエントラント、読み取りと書き込みの保護、または公平性などに関して、セマンティクスのロックを変更する方法はありません。
  • 同期はメソッドとブロック内で行われるため、厳密なブロック構造のロックに制限されます。つまり、は、あるメソッドでロックを取得し、別のメソッドでロックを解放することはできません。

タイムアウト後にバックアウトすることが重要な場合は、セマフォを使用してください。そうでなければ、モニターは正常です。

7

あなたは頭痛最小化の後にある場合は、ロックプリミティブの真の選択肢を感じるところはどこでも、はセマフォを超えるモニター(​​ブロック/メソッド)を好みます。 セマフォの柔軟性に関する学術的な話を無視してください。あなたは構成可能性ではなく信頼性の後ろにいますか?

モニタとセマフォが同等である(互いにシミュレートできる)と主張されていますが、この同等性は、はるかに抽象的であり、sometimes expectedよりも役立ちません。 正しくをシミュレートできる人は、この質問に対する回答はもう必要ありません。

明らかに、セマフォは、同時にブロックに入ることを許可されるスレッドの数が1より大きい状況で唯一実用的な選択肢です。したがって、モニタの実際の競合相手は、バイナリセマフォです。つまり、カウントが1で初期化され、さらに、セマフォのロックを解除するためにロックを行ったスレッドと同じスレッドを期待するものだけです。ですから、まさにそのような状況をもっと見てみましょう。

モニタとバイナリセマフォの基本的な違いは、スレッド所有者です。それは大きな結果をもたらし、それはリエントラントの能力です。再入可能とは、すでにロックを所有しているスレッドが、デッドロックとは対照的に、再度ロックを獲得できることを意味します。これは、あなたのクラスがすべてのメソッドで単純に保護したいという状態を共有していても、これらのメソッドが互いに呼び出す方法について永続的な前提を与えることはできません。一般的にあなたのスレッドセーフティスキームで進化していくベルトやブレースの特性を持っています。

セマフォは決してリエントラントではなく、Javaモニタは常にリエントラントです。同じオブジェクトを多くのコード位置からロックする必要がある場合は、シングルスレッドのシナリオでもsemaphores are prone to deadlocksがあります。このようなセマフォの制限は、モニタが実際にはオプションではない比較的まれなシナリオでのみ役立ちます。

スレッド所有権は、ロックを忘れたり、ロックを解除したり、あるスレッドのアクティビティを別のスレッドの動作を隠すことを劇的に減らします。関連するJava構文にも人間工学に大きな違いがあります。

通知this question;別の用語を使用していますが、そこでのより良い答えは、Javaの「モニター」を意味する「ミューテックス」を理解しています。

関連する問題