搜索
写经验 领红包
 > 游戏

java产生死锁的原因(java产生死锁的四个必要条件)

在生活中,很多人可能想了解和弄清楚什么情况下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程序会产生死锁?如何定位、修复?内容介绍后,相信大家有新的了解,更希望可以对你有所帮助。