java - 寻找有关如何避免死锁的建议
问题描述
我在我的应用程序中遇到了与此类似的情况:
public class Example {
private static A aClass = new A();
private static B bClass = new B();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
bClass.start();
}
}, ">>>>>>>>>>").start();
new Thread(new Runnable() {
@Override
public void run() {
aClass.start();
}
}, "__________").start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
detectDeadlock();
}
private static void detectDeadlock() {
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
long[] threadIds = threadBean.findMonitorDeadlockedThreads();
int deadlockedThreads = threadIds != null? threadIds.length : 0;
System.out.println("Number of deadlocked threads: " + deadlockedThreads);
}
private static class A {
private final Object aLock = new Object();
public void start() {
System.out.println(Thread.currentThread()+ " " + "A-start; waiting for aLock");
synchronized (aLock) {
System.out.println(Thread.currentThread()+ " " + "A-start; acquired aLock");
bClass.synchronizedMethod();
}
System.out.println(Thread.currentThread()+ " " + "A-start; release aLock");
}
public void synchronizedMethod() {
System.out.println(Thread.currentThread()+ " " + "A-synchronizedMethod; waiting for aLock");
synchronized (aLock) {
System.out.println(Thread.currentThread()+ " " + "A-synchronizedMethod; acquired aLock");
}
System.out.println(Thread.currentThread()+ " " + "A-synchronizedMethod; release aLock");
}
}
private static class B {
private final Object bLock = new Object();
public void synchronizedMethod() {
System.out.println(Thread.currentThread()+ " " + "B-synchronizedMethod; waiting for bLock");
synchronized (bLock) {
System.out.println(Thread.currentThread()+ " " + "B-synchronizedMethod; acquired bLock");
}
System.out.println(Thread.currentThread()+ " " + "B-synchronizedMethod; release bLock");
}
public void start() {
System.out.println(Thread.currentThread() + " " + "B-Start; waiting for bLock");
synchronized (bLock) {
System.out.println(Thread.currentThread()+ " " + "B-Start; acquired bLock");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
aClass.synchronizedMethod();
}
System.out.println(Thread.currentThread()+ " " + "B-Start; released bLock");
}
}
}
这个片段的输出是这样的:
Thread[>>>>>>>>>>,5,main] B-Start; waiting for bLock
Thread[>>>>>>>>>>,5,main] B-Start; acquired bLock
Thread[__________,5,main] A-start; waiting for aLock
Thread[__________,5,main] A-start; acquired aLock
Thread[__________,5,main] B-synchronizedMethod; waiting for bLock
Thread[>>>>>>>>>>,5,main] A-synchronizedMethod; waiting for aLock
Number of deadlocked threads: 2
我正在为这种僵局情况寻找一些指导。
你能告诉我如何避免这种僵局吗?
解决方案
最后,我选择使用由 A 和 B 的两个实例共享的全局锁。
代码看起来像这样:
private static class Lock {
private static Lock lock = new Lock();
private Lock(){}
public static Lock getLock() {return lock;}
}
private static class A {
private final Object aLock = Lock.getLock();
// ...
}
private static class B {
private final Object bLock = Lock.getLock();
// ...
}
推荐阅读
- mule - Why does Mule DataWeave array map strip top level objects?
- sorbet - How do I install release build of sorbet?
- php - 从子 SKU Magento 2 获取父 SKU(可配置或捆绑)
- vba - SAP 连接为空时运行时错误“91”
- android - 我想获取单击的课程按钮的 ID 并加载该 ID 的数据
- python-3.x - 有没有办法用一些重复的元素对未排序的列表进行排序?
- function - How to use a signal as function parameter in CAPL
- c# - 在 C# 字典中查找元组键的问题
- django - 使用 django ORM 过滤三个表
- javascript - 在事件处理程序中调用函数会返回所需的结果,但引用该方法不会