Javaのミューテックスとセマフォとは何ですか?主な違いは何ですか?


回答:


115

セマフォはカウントできますが、ミューテックスは1までしかカウントできません。

クライアント接続を受け入れる実行中のスレッドがあるとします。このスレッドは、10クライアントを同時に処理できます。次に、新しいクライアントはそれぞれ、セマフォを10に達するまで設定します。セマフォに10個のフラグがある場合、スレッドは新しい接続を受け入れません。

ミューテックスは通常、ものを保護するために使用されます。10個のクライアントがシステムの複数の部分にアクセスできるとします。次に、システムの一部をミューテックスで保護して、1つのクライアントがそのサブシステムに接続されているとき、他の誰もアクセスできないようにすることができます。この目的にもセマフォを使用できます。mutexは「相互排除セマフォ」です。


4
これは真実ではありません。同じスレッドが同じmutexに2回以上入ることができるため、エントリ `&exitのバランスをとるためにカウントを維持する必要があります。
finnw 2009

1
@finnw、一般に、mutexには再帰的と非再帰的な2種類のmutexがあります。Javaはデフォルトで再帰型を使用しますか?
edA-qa mort-ora-y 2011

2
@ edA-qa mort-ora-y、「Mutex」という用語はJava VMまたはAPI仕様では使用されていないため、すべてのオブジェクトに組み込まれているモニターを指していると想定しています。これは、Mutexと呼ばれるWin32オブジェクトにも似ています。 。同じことがに適用されますReentrantLock。これらはすべて再帰的です。私は非再帰的ミューテックスの「実際の」例を知りません(教科書でしか見たことがないので)とは考えませんでした。
finnw 2011

2
非再帰的mutexは、カウント1のセマフォを使用して実装できます。これは、再帰的な呼び出しを防ぎたい場合に役立ちます。これには実用的な用途があります。私は個人的に大きなプロジェクトで初期化コードのループを検出するために使用しました(AがBを初期化し、Aが再度Aを初期化しようとします)。
Alexander Torstling

1
C ++ 11(C ++ 0x)標準では、mutexは非再帰的です。それらはそれを必要とする人のために別個の 'recursive_mutex'も提供します。ここでJavaについて話していることは承知していますが、今では多くの言語が言語を越えてコーディングしています。
Aditya Kumar Pandey 2013年

139

残念ながら、セマフォとミューテックスの最も重要な違いを見逃している人がいます。「所有権」の概念。

セマフォには所有権の概念がないため、どのスレッドでもセマフォを解放できます(これにより、多くの問題が発生する可能性がありますが、「死の検出」に役立ちます)。一方、ミューテックスには所有権の概念があります(つまり、取得したミューテックスのみを解放できます)。
並行システムを安全にプログラミングするには、所有権が非常に重要です。私は常にセマフォよりもミューテックスを使用することをお勧めします(ただし、パフォーマンスに影響があります)。

ミューテックスは、優先度の継承(優先度の逆転の問題に役立つ)と再帰(1種類のデッドロックを排除する)もサポートします。

「バイナリ」セマフォと「カウント/一般」セマフォがあることも指摘する必要があります。Javaのセマフォはカウンティングセマフォであるため、1より大きい値で初期化できます(指摘されているように、ミューテックスは概念的に1しかカウントできません)。これの有用性は他の投稿で指摘されています。

まとめると、管理するリソースが複数ない限り、セマフォよりもミューテックスを常にお勧めします。


1
Feabhasの答えは非常に重要です。mutexは、mutexを解放しようとするスレッドが実際に所有しているスレッドをチェックします。これはインタビューの質問として受け取ったので、覚えておく価値はあります。
Andrew pate

40

ミューテックスは基本的に相互排除です。一度に1つのスレッドのみがリソースを取得できます。1つのスレッドがリソースを取得すると、リソースを所有するスレッドが解放されるまで、他のスレッドはリソースを取得できません。リソースの取得を待機しているすべてのスレッドがブロックされます。

セマフォは、実行中のスレッドの数を制御するために使用されます。リソースの固定セットがあります。リソースカウントは、スレッドが所有するたびに減少します。セマフォカウントが0に達すると、他のスレッドはリソースを取得できなくなります。スレッドは、リソース解放を所有する他のスレッドまでブロックされます。

つまり、主な違いは、一度にリソースを取得できるスレッドの数です。

  • Mutex-そのONE。
  • セマフォ-そのDEFINED_COUNT(セマフォ数と同じ数)

8

mutexはリソースへのシリアルアクセスに使用され、セマフォはリソースへのアクセスを設定された数まで制限します。mutexは、アクセスカウントが1のセマフォと考えることができます。セマフォカウントを何に設定しても、リソースがブロックされる前にスレッドがリソースにアクセスできる場合があります。



3

mutexは、しばしばバイナリセマフォとして知られています。セマフォはゼロ以外のカウントで作成できますが、ミューテックスは概念的には上限が1のセメフォアです。



1

セマフォ

カウントするセマフォ。概念的には、セマフォは一連の許可を保持します。acquire()許可が得られるまで、必要に応じて各ブロックを行い、許可を取得します。それぞれrelease()が許可を追加し、潜在的にブロッキング取得者を解放します。ただし、実際の許可オブジェクトは使用されません。セマフォは、利用可能な数のカウントを保持し、それに応じて動作します。

セマフォは、いくつかの(物理的または論理的)リソースにアクセスできるスレッドの数を制限するためによく使用されます。

Javaには組み込みのMutex APIがありません。ただし、バイナリセマフォとして実装できます。

1に初期化され、使用可能な許可が1つだけになるように使用されるセマフォは、相互排他ロックとして機能できます。これは2つの状態しかないため、一般的にバイナリセマフォとして知られています。1つのパーミットが使用可能か、またはゼロのパーミットが使用可能です。

この方法で使用すると、バイナリセマフォには、多くのLock実装とは異なり、所有者以外のスレッドが「ロック」を解放できるという特性があります(セマフォには所有権の概念がないため)。。これは、デッドロック回復などの一部の特殊なコンテキストで役立ちます。

だから、重要な相違点セマフォとミューテックスの間:

  1. セマフォは、許可されたリソースにアクセスするスレッドの数を制限します。Mutexでは、リソースにアクセスできるスレッドは1つだけです。

  2. セマフォを所有するスレッドはありません。スレッドはacquire()release()メソッドを呼び出すことで、許可の数を更新できます。mutexは、ロックを保持しているスレッドによってのみロック解除されます。

  3. mutexが条件変数と共に使用される場合、暗黙のブラケットがあり、プログラムのどの部分が保護されているかは明らかです。これは、セマフォの場合に必ずしも当てはまりません。これは、並行プログラミングのgo toと呼ばれる可能性があります。強力ですが、非構造化された不確定な方法で使用するのは簡単です。


0

Mutexはバイナリセマフォです。先着順の原則が満たされるように、1で初期化する必要があります。これは、各ミューテックスの他の特別なプロパティに私たちをもたらします:やった1 ダウンでは、ないものでなければなりませんアップ。エルゴ我々はいくつかのリソースについて相互排除を取得しました。

ここで、mutexが一般的なセマフォの特殊なケースであることがわかります。


0

同期対象のセマフォ古典的な信号機を実装します。信号機は、カウンターが共有するリソースへのアクセスを制御します。カウンターがゼロより大きい場合、アクセスが許可されます。ゼロの場合、アクセスは拒否されます。カウンターは、共有リソースへのアクセスを許可するアクセス許可をカウントします。次に、リソースにアクセスするには、スレッドが信号機から許可を受け取る必要があります。一般に、信号機を使用するために、共有リソースにアクセスしたいスレッドは許可を取得しようとします。信号数がゼロより大きい場合、スレッドは許可を取得し、信号数は減分されます。それ以外の場合、スレッドは許可を得るまでロックされます。スレッドが共有リソースにアクセスする必要がなくなると、スレッドは許可を解放するため、信号数が増加します。許可を待っている別のスレッドがある場合、その時に許可を取得します。JavaのSemaphoreクラスはこのメカニズムを実装しています。

セマフォには2つのビルダーがあります。

Semaphore(int num)
Semaphore(int num, boolean come)

numは、許可の初期カウントを指定します。次に、numは、特定の時間に共有リソースにアクセスできるスレッドの数を指定します。numが1の場合、一度に1つのスレッドでリソースにアクセスできます。comeをtrueに設定することで、待機しているスレッドに、要求された順序でアクセス許可が付与されることを保証できます。


0

あなたは比類のないものを比較します、技術的にはセマフォとそれが意味をなさないミューテックスの間に違いはありません。Mutexは、アプリケーションロジック内の任意の名前と同様に重要な名前です。つまり、セマフォを「1」に初期化します。これは、一般に、リソースまたは保護された変数を保護して相互排除を保証するために使用されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.