Есть ли мьютекс в 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();
}
будет ли приведенный выше код гарантировать, что семафор будет двоичным?
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 Implementationtry { 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