Java 中获取多个锁的常见模式如下:
synchronized (lock1) {
...
synchronized(lock2) {
}
}
这是死锁的常见原因,因为如果另一个线程的顺序相反,即:
synchronized (lock2) {
...
synchronized(lock1) {
}
}
那么没有线程能够继续进行。两者都被无限期阻止。
C++ 提供了 scoped_lock构造以原子方式获取多个锁:
When a scoped_lock object is created, it attempts to take ownership of the mutexes it is given. When control leaves the scope in which the scoped_lock object was created, the scoped_lock is destructed and the mutexes are released. If several mutexes are given, deadlock avoidance algorithm is used as if by std::lock.
Java有这样的东西吗?
最佳答案
Does Java have such a thing?
你不能使用 Java 原始互斥体来做到这一点;即同步
。
但是,如果您使用 Lock 对象而不是原始互斥体,则可以使用 Lock.tryLock 实现这种行为。例如。
Lock lock1 ...
Lock lock2 ...
lock1.lock(); // This blocks until the lock is acquired
try {
if (lock2.tryLock()) { // NB: this does not block ... so no deadlock
try {
// Do stuff
} finally {
lock2.unlock();
}
} else {
System.out.println("Potential deadlock avoided!");
}
} finally {
lock1.unlock();
}
请注意,为此您必须使用try ...finally。由于锁
不能自动关闭,尝试使用资源不会释放锁。
更多详情,请参阅javadocs对于Lock
接口(interface)。
值得注意的是,虽然上述不会死锁,但仍然存在(理论上)活锁的风险,即两个线程循环上述代码并反复避免死锁......但没有取得实际进展。
正如评论者所指出的,避免死锁的另一种方法是设计应用程序,以便始终以相同的顺序获取锁对。
关于java - 如何在Java中原子地获取多个锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77026683/