您的位置 首页 技术

如何解决java中的死锁问题

一、死锁的定义 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。 那么我们换一个更加规范的定义:集…

一、死锁的定义

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

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

免费视频教程推荐:java免费视频教程

二、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() {@Overridepublic 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() {@Overridepublic 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> jps1256 ImitateDeadLock9240 Jps7548 org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar

jstack : 查看堆栈信息

执行 jstack 命令后,会显示出两个线程互相等待,产生了死锁。

C:\Users\31415>jstack 1256Java 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入门学习

以上就是如何解决java中的死锁问题的详细内容,更多请关注24课堂在线网其它相关文章!

本文来自网络,不代表24小时课堂在线立场,转载请注明出处:https://www.24ketang.cn/11418.html

为您推荐

返回顶部