Java のミューテックスとセマフォとは何ですか? 主な違いは何ですか?
11 に答える
残念ながら、誰もがセマフォとミューテックスの最も重要な違いを見落としています。「所有」という概念。
セマフォには所有権の概念がありません。これは、任意のスレッドがセマフォを解放できることを意味します (これは、それ自体で多くの問題を引き起こす可能性がありますが、「死の検出」には役立ちます)。一方、ミューテックスには所有権の概念があります (つまり、取得したミューテックスのみを解放できます)。
所有権は、並行システムの安全なプログラミングにとって非常に重要です。セマフォよりもミューテックスを使用することを常にお勧めします (ただし、パフォーマンスへの影響はあります)。
ミューテックスは、優先度の継承 (優先度の逆転の問題を解決するのに役立ちます) と再帰 (1 つのタイプのデッドロックを排除する) もサポートする場合があります。
「バイナリ」セマフォと「カウント/一般」セマフォがあることも指摘しておく必要があります。Java のセマフォはカウンティング セマフォであるため、1 より大きい値で初期化することができます (指摘したように、ミューテックスは概念的に 1 のカウントしかできません)。この有用性は、他の投稿で指摘されています。
要約すると、管理するリソースが複数ある場合を除き、セマフォよりもミューテックスを常にお勧めします。
セマフォはカウントできますが、ミューテックスは 1 までしかカウントできません。
クライアント接続を受け入れるスレッドが実行されているとします。このスレッドは、10 クライアントを同時に処理できます。次に、新しいクライアントごとに、セマフォが 10 に達するまでセマフォを設定します。セマフォに 10 個のフラグがある場合、スレッドは新しい接続を受け入れません。
Mutex は通常、何かを保護するために使用されます。10 台のクライアントがシステムの複数の部分にアクセスできるとします。次に、ミューテックスを使用してシステムの一部を保護できるため、1 つのクライアントがそのサブシステムに接続されている場合、他の誰もアクセスできません。この目的にもセマフォを使用できます。ミューテックスは「相互排除セマフォ」です。
Mutex は基本的に相互排除です。一度にリソースを取得できるスレッドは 1 つだけです。1 つのスレッドがリソースを取得すると、リソースを所有しているスレッドが解放されるまで、他のスレッドはそのリソースを取得できません。リソースの取得を待機しているすべてのスレッドがブロックされます。
セマフォは、実行するスレッドの数を制御するために使用されます。リソースの固定セットがあります。リソース数は、スレッドが同じものを所有するたびに減少します。セマフォ カウントが 0 に達すると、他のスレッドはリソースを取得できなくなります。スレッドは、リソースを所有する他のスレッドが解放されるまでブロックされます。
つまり、主な違いは、一度にリソースを取得できるスレッドの数です。
- Mutex -- その 1 つ。
- セマフォ -- その DEFINED_COUNT (セマフォの数だけ)
ミューテックスはリソースへのシリアルアクセスに使用され、セマフォはリソースへのアクセスを設定された数に制限します。ミューテックスは、アクセス カウントが 1 のセマフォと考えることができます。セマフォ カウントを何に設定しても、リソースがブロックされる前にスレッドがリソースにアクセスできる可能性があります。
ミューテックスは、バイナリ セマフォとしてよく知られています。セマフォはゼロ以外の任意のカウントで作成できますが、ミューテックスは概念的には上限カウントが 1 のセマフォです。
セマフォはカウント同期メカニズムですが、ミューテックスはそうではありません。
この質問には、関連する回答と公式の Java ガイダンスへのリンクがあります: Is there a Mutex in Java?
比類のないものを比較すると、技術的にはセマフォとミューテックスに違いはなく、意味がありません。Mutex は、アプリケーション ロジック内の任意の名前と同様に重要な名前です。これは、セマフォを「1」で初期化することを意味します。一般に、リソースまたは保護された変数を保護して相互排除を保証するために使用されます。