web-dev-qa-db-ja.com

Javaにミューテックスはありますか?

JavaにMutexオブジェクトがあるか、作成する方法はありますか? 1許可で初期化されたセマフォオブジェクトは私を助けないので、私は尋ねています。この場合を考えてください:

try {
   semaphore.acquire();
   //do stuff
   semaphore.release();
} catch (Exception e) {
   semaphore.release();
}

最初の取得で例外が発生した場合、catchブロックでのリリースにより許可が増加し、セマフォはバイナリセマフォではなくなります。

正しい方法はありますか?

try {
   semaphore.acquire();
   //do stuff
} catch (Exception e) {
   //exception stuff
} finally {
   semaphore.release();
}

上記のコードは、セマフォがバイナリであることを保証しますか?

104
Noam Nevo

このページを参照してください: http://www.Oracle.com/technetwork/articles/javase/index-140767.html

それはあなたが探しているものである(私が思う)わずかに異なるパターンを持っています:

try {
  mutex.acquire();
  try {
    // do something
  } finally {
    mutex.release();
  }
} catch(InterruptedException ie) {
  // ...
}

この使用法では、release()が成功した後にのみacquire()を呼び出しています。

107
payne

Javaのオブジェクトは、synchronizedブロックを使用してロックとして使用できます。これにより、例外が発生したときにロックが自動的に解除されます。

Object someObject = ...;

synchronized (someObject) {
  ...
}

詳細については、こちらをご覧ください: Intrinsic Locks and Synchronization

123
casablanca
import Java.util.concurrent.locks.Lock;
import Java.util.concurrent.locks.ReentrantLock;


private final Lock _mutex = new ReentrantLock(true);

_mutex.lock();

// your protected code here

_mutex.unlock();
23
Argv

誰もこれについて明確に言及していませんが、この種のパターンは通常セマフォには適していません。その理由はanyスレッドはセマフォを解放できますが、通常は所有者スレッドのみが必要です 元々ロックされてロック解除できる 。この使用例では、Javaで通常、ReentrantLocksを使用します。これは次のように作成できます。

import Java.util.concurrent.locks.Lock;
import Java.util.concurrent.locks.ReentrantLock;

private final Lock lock = new ReentrantLock(true);

そして、使用法の通常の設計パターンは次のとおりです。

  lock.lock();
  try {
      // do something
  } catch (Exception e) {
      // handle the exception
  } finally {
      lock.unlock();
  }

ここ はJavaソースコードの例で、このパターンの動作を確認できます。

再入可能ロックには、公平性をサポートするという追加の利点があります。

セマフォは、非所有権解放セマンティクスが必要な場合にのみ使用してください。

6
rouble

私はあなたが試してみるべきだと思う:

セマフォの初期化中:

Semaphore semaphore = new Semaphore(1, true);

そして、Runnable Implementation

try 
{
   semaphore.acquire(1);
   // do stuff

} 
catch (Exception e) 
{
// Logging
}
finally
{
   semaphore.release(1);
}
5
Sashi Kant

Semaphoreがバイナリであることを確認するには、セマフォの作成時に許可数を1として必ず渡す必要があります。 Javadocs にはもう少し説明があります。

1

元の投稿の間違いは、tryループ内で設定されたacquire()呼び出しです。 「バイナリ」セマフォ(Mutex)を使用する正しいアプローチを次に示します。

semaphore.acquire();
try {
   //do stuff
} catch (Exception e) {
   //exception stuff
} finally {
   semaphore.release();
}
1
smile-on

各オブジェクトのロックは、Mutex/Semaphoreの設計とほとんど異なりません。たとえば、前のノードのロックを解除して次のノードをキャプチャして、リンクされたノードのトラバースを正しく実装する方法はありません。しかし、mutexを使用すると簡単に実装できます。

Node p = getHead();
if (p == null || x == null) return false;
p.lock.acquire();  // Prime loop by acquiring first lock.
// If above acquire fails due to interrupt, the method will
//   throw InterruptedException now, so there is no need for
//   further cleanup.
for (;;) {
Node nextp = null;
boolean found;
try { 
 found = x.equals(p.item); 
 if (!found) { 
   nextp = p.next; 
   if (nextp != null) { 
     try {      // Acquire next lock 
                //   while still holding current 
       nextp.lock.acquire(); 
     } 
     catch (InterruptedException ie) { 
      throw ie;    // Note that finally clause will 
                   //   execute before the throw 
     } 
   } 
 } 
}finally {     // release old lock regardless of outcome 
   p.lock.release();
} 

現在、Java.util.concurrentにはそのようなクラスはありませんが、Mutextの実装は Mutex.Java にあります。標準ライブラリに関しては、Semaphoreはこのすべての機能を提供します。

1
pogrebniuk