java 解决死锁_如何解决java中的死锁问题

本文介绍了Java中的死锁现象,通过代码实例展示了死锁如何发生,并提供了利用Jps和Jstack命令诊断死锁的方法。此外,还提出了两种解决死锁的策略:一是规定获取锁的顺序,二是使用Lock接口的超时尝试获取锁机制。
摘要由CSDN通过智能技术生成

08c8574a95d7318e3d6852c3a29ec8f6.png

一、死锁的定义

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

那么我们换一个更加规范的定义:集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。

二、Java 代码模拟死锁

代码示例:/**

* 模拟死锁类

* */

public class ImitateDeadLock {

public static void main(String[] args) {

final Object a=new Object();

final Object b=new Object();

//线程 threadA 获取对象 a 的锁之后,休眠10秒, 尝试获取对象 b 的锁

Thread threadA=new Thread(new Runnable() {

@Override

public void run() {

synchronized (a) {

System.out.println("threadA 获取到对象 a 的锁");

try {

Thread.sleep(10000);

synchronized (b) {

System.out.println("threadA 获取到对象 b 的锁");

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

//线程 threadB 获取对象 b 的锁之后,休眠10秒, 尝试获取对象 a 的锁

Thread threadB=new Thread(new Runnable() {

@Override

public void run() {

synchronized (b) {

System.out.println("threadB 获取到对象 b 的锁");

try {

Thread.sleep(10000);

synchronized (a) {

System.out.println("threadB 获取到对象 a 的锁");

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

threadA.start();

threadB.start();

}

}

运行结果:threadA 获取到对象 a 的锁

threadB 获取到对象 b 的锁

无限等待........

三、如何解决

1、确认问题

(1)Jps + Jstack 命令

Jps : 查看当前进程

如下所示, class 名称为ImitateDeadLock的进程为我们需要查看的进程。C:\Users\31415> jps

1256 ImitateDeadLock

9240 Jps

7548 org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar

jstack : 查看堆栈信息

执行 jstack 命令后,会显示出两个线程互相等待,产生了死锁。C:\Users\31415>jstack 1256

Java stack information for the threads listed above:

===================================================

"Thread-1":

at ImitateDeadLock$2.run(ImitateDeadLock.java:37)

- waiting to lock <0x048b15a8> (a java.lang.Object)

- locked <0x048b15b0> (a java.lang.Object)

at java.lang.Thread.run(Thread.java:745)

"Thread-0":

at ImitateDeadLock$1.run(ImitateDeadLock.java:17)

- waiting to lock <0x048b15b0> (a java.lang.Object)

- locked <0x048b15a8> (a java.lang.Object)

at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

2、处理问题

(1)确定的顺序获取锁

例如:我们上面的 Demo 中,两个线程获取锁的顺序都为 先获取对象 a 的锁,在获取对象 b 的锁,就不会出现死锁的问题。

(2)超时放弃

当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。

想了解更多相关教程请访问:java入门学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值