java产生死锁的原因(java产生死锁的四个必要条件)
在生活中,很多人可能想了解和弄清楚什么情况下Java程序会产生死锁?如何定位、修复?的相关问题?那么关于java产生死锁的原因的答案我来给大家详细解答下。
死锁 deadlock
是一种特定的程序状态,由于循环依赖导致彼此一直处于等待之中,没有一方可以继续前进。
定位deadlock 最常见的方式
就是使用jstack 等工具获取线程栈,然后定位互相之间的依赖关系,进而找到死锁。
使用2个嵌套的synchronized 去获取锁,实现一个基本的deadlock 程序:
public class DeadLockSample extends Thread {
private String first;
private String second;
public DeadLockSample(String threadName, String first, String second){
super(threadName);
this.first = first;
this.second = second;
}
public void run(){
synchronized (first){
System.out.println(this.getName() +" obtained: " + first);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (second){
System.out.println(this.getName() + " obtained: " + second);
}
}
}
public static void main(String[] args) throws InterruptedException {
String lockA = "lockA";
String lockB = "lockB";
DeadLockSample t1 = new DeadLockSample("Thread1", lockA, lockB);
DeadLockSample t2 = new DeadLockSample("Thread2", lockB, lockA);
t1.start();
t2.start();
t1.join();
t2.join();
}
}
输出结果:
Thread1 obtained: lockA
Thread2 obtained: lockB
打印结果是随机的,因为线程的调度依赖于(操作系统)调度器。
jvisualvm 工具
通过 jvisualvm 工具,可以查看到deadlock 信息,如下所示:
调用 jstack 获取线程栈
${JAVA_HOME}\bin\jstack your_pid
首先,可以使用 jps 或者系统的 ps 命令、任务管理器等等工具,确定进程ID。
jstack 28336
输出结果,显示发现了一个deadlock:
如何避免deadlock?
如果可能的话,尽量避免使用多个锁,并且只有需要时才持有锁。如果必须使用多个锁,尽量设计好锁的获取顺序。使用带超时的方法,为程序带来更多可控性。温馨提示:通过以上关于什么情况下Java程序会产生死锁?如何定位、修复?内容介绍后,相信大家有新的了解,更希望可以对你有所帮助。