Есть ли Mutex в Java?
Есть ли объект Mutex в java или способ его создания?
Я спрашиваю, потому что объект Semaphore, инициализированный с 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();
}
Будет ли указанный код гарантировать, что семафор будет двоичным?
Ответы
Ответ 1
Смотрите эту страницу: http://www.oracle.com/technetwork/articles/javase/index-140767.html
У этого есть немного другой образец, который (я думаю), что вы ищете:
try {
mutex.acquire();
try {
// do something
} finally {
mutex.release();
}
} catch(InterruptedException ie) {
// ...
}
В этом использовании вы вызываете release()
только после успешного acquire()
Ответ 2
Любой объект в Java может использоваться как блокировка с помощью блока synchronized
. Это также автоматически позаботится об освобождении блокировки при возникновении исключения.
Object someObject = ...;
synchronized (someObject) {
...
}
Подробнее об этом можно узнать здесь: Внутренние блокировки и синхронизация
Ответ 3
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();
Ответ 4
Я думаю, вам стоит попробовать:
Инициализация семафора:
Semaphore semaphore = new Semaphore(1, true);
И в вашем Runnable Implementation
try
{
semaphore.acquire(1);
// do stuff
}
catch (Exception e)
{
// Logging
}
finally
{
semaphore.release(1);
}
Ответ 5
Чтобы гарантировать, что a Semaphore
является двоичным, вам просто нужно убедиться, что вы передаете количество разрешений как 1 при создании семафора. Javadocs имеют немного больше объяснений.
Ответ 6
Каждый блокирующий объект немного отличается от дизайна Mutex/Semaphore.
Например, нет возможности правильно реализовать перемещение связанных узлов с выпуском предыдущей блокировки node и последующим захватом. Но с мьютексом его легко реализовать:
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 предоставляет всю эту функциональность и многое другое.
Ответ 7
Ошибка в исходном сообщении - вызов() вызова, установленный внутри цикла try.
Вот правильный подход к использованию "двоичного" семафора (Mutex):
semaphore.acquire();
try {
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
Ответ 8
Никто не сказал об этом явно, но этот тип шаблона обычно не подходит для семафоров. Причина в том, что любой поток может освобождать семафор, но обычно вам нужен только поток владельца, который изначально заблокирован, чтобы иметь возможность разблокировать. Для этого случая использования в 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, где вы можете увидеть этот шаблон в действии.
Реэкрант-блокировки имеют дополнительное преимущество для обеспечения справедливости.
Используйте семафоры только в том случае, если вам нужна семантика без права собственности.
Ответ 9
Если вам нужен только один поток в критическом разделе, зайдите в синхронизированные методы или locks.
Ответ 10
Посмотрите на javadoc для java.util.concurrent.locks.AbstractQueuedSynchronizer. В нем есть пример того, как написать класс Mutex.
-dbednar