Есть ли объект 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();
}
Будет ли приведенный выше код гарантировать, что семафор будет двоичным?
Ответы:
См. Эту страницу: http://www.oracle.com/technetwork/articles/javase/index-140767.html
У него немного другой шаблон, который (я думаю) то, что вы ищете:
В этом случае вы звоните только
release()
после успешногоacquire()
источник
Любой объект в Java можно использовать в качестве блокировки с помощью
synchronized
блока. Это также автоматически позаботится о снятии блокировки при возникновении исключения.Вы можете узнать больше об этом здесь: Внутренние блокировки и синхронизация
источник
synchronized
вы увидите, что лучше читается и менее подвержено ошибкам.transaction.begin(); transaction.commit()
).someObject.wait(timeout)
иsomeObject.notify()
пока смотрите код этого ответа.источник
"Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements."
от: docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ ... ... хотя вы правы . Ответ Argv не иллюстрирует и не объясняет эти операции.private final ReentrantLock _mutex = ...
, вы можете использовать getHoldCount (), чтобы вернуть количество повторных блокировок потока. (Вы можете применить a,Condition
чтобы предотвратить это. См. API .)Никто не упомянул об этом четко, но такой шаблон обычно не подходит для семафоров. Причина в том, что любой поток может освободить семафор, но обычно вам нужен только поток-владелец, который изначально заблокирован, чтобы иметь возможность разблокировать . Для этого варианта использования в Java мы обычно используем ReentrantLocks, которые можно создать следующим образом:
И обычный шаблон использования дизайна:
Вот пример исходного кода Java, где вы можете увидеть этот шаблон в действии.
У повторных блокировок есть дополнительное преимущество в виде поддержки справедливости.
Используйте семафоры только в том случае, если вам нужна семантика без права собственности.
источник
count=1
не является блокировкой взаимного исключения.lock
например , ? Я не знаю , почему и принимаются приравнены быть тем же лицом. может быть выпущен любым потоком, поэтому это не может гарантировать защиту . Есть предположения?ReentrantLock
mutex
mutex
binary semaphore
Semaphore
critical section
Я думаю, вам стоит попробовать:
При инициализации семафора:
И в твоем
Runnable Implementation
источник
Ошибка в исходном посте - это вызов функции Accele (), установленный внутри цикла try. Вот правильный подход к использованию «двоичного» семафора (Mutex):
источник
Чтобы гарантировать, что a
Semaphore
является двоичным, вам просто нужно убедиться, что вы передаете количество разрешений как 1 при создании семафора. В Javadocs есть немного больше объяснений.источник
Блокировка каждого объекта мало отличается от дизайна мьютексов / семафоров. Например, нет способа правильно реализовать обход связанных узлов с снятием блокировки предыдущего узла и захватом следующего. Но с мьютексом легко реализовать:
В настоящее время такого класса нет
java.util.concurrent
, но вы можете найти реализацию Mutext здесь Mutex.java . Что касается стандартных библиотек, Semaphore предоставляет все эти функции и многое другое.источник