web-dev-qa-db-ja.com

バイナリセマフォとReentrantLock

私は再入可能ロックとセマフォ(再入可能ロックの入れ子と解放/ロック解除のメカニズムの入れ子)を理解しようと努めてきました。

Release()メソッドは、パーミットを解放するスレッドが実際にパーマを保持しているかどうかをチェックしないため、セマフォを使用するには、より徹底的にテストされたアプリケーションを作成する必要があるようです。テストコードをテストしたところ、許可の数が最初の制限を超えて増加する可能性があることがわかりました。一方、スレッドがunlockメソッドを呼び出したときに再入可能ロックを保持していない場合、IllegalMonitorExceptionが発生します。

したがって、バイナリセマフォで実行できることはすべてReentrantLockでも実行できるため、バイナリセマフォを使用する本当の理由はないというのは正しいことでしょう。バイナリセマフォを使用する場合は、メソッドコールスタック全体をチェックして、許可が以前に取得されたかどうかを確認する必要があります(後続の取得の可能性がある場合も許可が解放されたかどうか-解放が続行しない場合にブロックされ、など)。また、再入可能ロックはオブジェクトごとに1つのロックも提供するため、バイナリセマフォよりも再入可能ロックを優先する方が常に良い方法ではないでしょうか。

バイナリセマフォとミューテックスの違いについての記事をここで確認しましたが、Javaのミューテックスのようなものはありますか?

ありがとう、チャン。

PS-私は別のフォーラムにこの質問を投稿しました( http://www.coderanch.com/t/615796/threads/Java/reason-prefer-binary-Semaphore-Reentrant )そして私は持っていませんまだ応答を受け取っていません。ここにも投稿して、何が手に入るか見てみようと思いました。

32
Chan

バイナリセマフォで実行できることはすべてReentrantLockでも実行できるため、バイナリセマフォを使用する本当の理由はありません。

必要なのは、再入可能な相互排除だけであれば、はい、ReentrantLockでバイナリセマフォを使用する理由はありません。何らかの理由で所有権を解放しないセマンティクスが必要な場合は、明らかにセマフォが唯一の選択肢です。

また、再入可能ロックはオブジェクトごとに1つのロックも提供するため、バイナリセマフォよりも再入可能ロックを優先する方が常に良い方法ではないでしょうか。

それは必要に依存します。前に説明したように、単純なミューテックスが必要な場合は、セマフォを選択しないでください。複数のスレッド(制限された数)がクリティカルセクションに入る可能性がある場合は、スレッド制限またはセマフォのいずれかを使用してこれを行うことができます。

バイナリセマフォとミューテックスの違いについての記事をここで確認しましたが、Javaのミューテックスのようなものはありますか?

ReentrantLocksynchronizedは、Javaのmutexの例です。

33
John Vint

Johnはすでに上記の適切な説明と、ミューテックスの例をJavaとSynchronizedキーワードとともに提供しているため、再入可能ロックについては説明しません。

ただし、何らかの理由でロックメカニズムをより適切に制御したい場合は、セマフォを使用すると便利です。つまり、セマフォは本質的にブラインドなので、コードは、acquire()を呼び出し、誰がrelease()を呼び出したのかを担当する必要があります。

Javaを使用した独自のmutex実装の別のアプローチはLockSupportです。これはセマフォと少し似ていますが、park()関数を使用してパーミットにタイムアウトがあり、セマフォとは異なり、一度に1つのパーミットのみをサポートしますそれらの複数をサポートします。

7
Ashley

セマフォと再入可能ロックの間にはいくつかの小さな違いがあります。

  • セマフォは別のスレッドによって解放される可能性があります。セマフォのjavadocは、このような動作はデッドロック回復などの特殊なコンテキストで役立つ可能性があると述べています。ですから、それは本当に専門的な文脈であるべきです。
  • また、バイナリセマフォは再入可能ではありません。同じスレッドで2度目にバイナリセマフォを取得することはできません。デッドロック(それ自体でスレッドをデッドロックする!)につながり、すでに述べたデッドロック回復の手段が必要になる場合があります。
0