Есть ли мьютекс в Java?



есть ли объект мьютекса в java или способ его создания?
Я спрашиваю, потому что Семафорный объект, инициализированный с 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();
}


будет ли приведенный выше код гарантировать, что семафор будет двоичным?

623   8  

8 ответов:

смотрите эту страницу:http://www.oracle.com/technetwork/articles/javase/index-140767.html

Он имеет немного другой шаблон, который (я думаю), что вы ищете:

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

в этом использовании вы только вызываете release() после успешного acquire()

любой объект в Java может быть использован в качестве блокировки с помощью synchronized блок. Это также автоматически позаботится о снятии блокировки при возникновении исключения.

Object someObject = ...;

synchronized (someObject) {
  ...
}

Вы можете прочитать больше об этом здесь: встроенные блокировки и синхронизация

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();

Я думаю, что вы должны попробовать с :

при инициализации семафора :

Semaphore semaphore = new Semaphore(1, true);

и в Runnable Implementation

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

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

никто четко не упомянул об этом, но этот вид шаблона обычно не подходит для семафоров. причина в том, что любой поток может освободить семафор, но обычно вы только хотите владелец-нить это первоначально заблокирован, чтобы иметь возможность разблокировать. Для этого случая использования, в 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, где вы можете посмотреть этот шаблон в действии.

Реентерабельные блокировки имеют дополнительное преимущество поддержки справедливости.

используйте семафоры только в том случае, если вам нужна семантика non-ownership-release.

чтобы убедиться, что a Semaphore является двоичным вам просто нужно убедиться, что вы передаете количество разрешений как 1 при создании семафора. Элемент Javadocs есть немного больше объяснений.

ошибка в исходном сообщении-это вызов acquire (), установленный внутри цикла try. Вот правильный подход к использованию "двоичного" семафора (мьютекса):

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

блокировка каждого объекта немного отличается от дизайна мьютекса/семафора. Например, нет способа правильно реализовать обход связанных узлов с освобождением блокировки предыдущего узла и захватом следующего. Но с мьютексом это легко реализовать:

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 здесь мьютекс.java. Что касается стандартных библиотек, то семафор предоставляет весь этот функционал и многое другое.

Comments

    Ничего не найдено.