Java中有Mutex吗?
在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();
}
上面的代码会确保信号量是二进制的吗?
8个解决方案
121 votes
Java中的任何对象都可以使用synchronized块作为锁。 当发生异常时,这也将自动解除锁定。
Object someObject = ...;
synchronized (someObject) {
...
}
你可以在这里阅读更多相关内容:内在锁定和同步
casablanca answered 2019-07-27T21:29:12Z
106 votes
见此页:[http://www.oracle.com/technetwork/articles/javase/index-140767.html]
它有一个略有不同的模式,(我认为)你在寻找什么:
try {
mutex.acquire();
try {
// do something
} finally {
mutex.release();
}
} catch(InterruptedException ie) {
// ...
}
在此用法中,您仅在成功完成acquire()后致电release()
payne answered 2019-07-27T21:28:41Z
23 votes
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();
Argv answered 2019-07-27T21:29:30Z
6 votes
没有人明确提到这一点,但这种模式通常不适合信号量。 原因是任何线程都可以释放信号量,但您通常只希望最初锁定的所有者线程能够解锁。 对于这个用例,在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源代码中的示例,您可以在其中看到此模式的实际应用。
折返锁具有支持公平性的额外好处。
仅在需要非所有权释放语义时才使用信号量。
rouble answered 2019-07-27T21:30:21Z
4 votes
我想你应该尝试:
信号量初始化时:
Semaphore semaphore = new Semaphore(1, true);
在你的Runnable Implementation
try
{
semaphore.acquire(1);
// do stuff
}
catch (Exception e)
{
// Logging
}
finally
{
semaphore.release(1);
}
Sashi Kant answered 2019-07-27T21:30:59Z
1 votes
要确保Semaphore是二进制文件,您只需确保在创建信号量时将许可证数量传递为1。 Javadocs有更多的解释。
Sanjay T. Sharma answered 2019-07-27T21:31:24Z
1 votes
原始帖子中的错误是try循环内的acquire()调用集。这是使用“二进制”信号量(Mutex)的正确方法:
semaphore.acquire();
try {
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
smile-on answered 2019-07-27T21:31:48Z
1 votes
每个对象的锁定与Mutex / Semaphore设计略有不同。例如,没有办法正确实现遍历链接节点,释放前一个节点的锁并捕获下一个节点。 但是使用互斥锁很容易实现:
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中没有此类,但您可以在此处找到Mutex实现Mutex.java。 至于标准库,Semaphore提供所有这些功能以及更多功能。
pogrebniuk answered 2019-07-27T21:32:21Z