热门IT资讯网

怎样解决java中的死锁问题

发表于:2024-11-28 作者:热门IT资讯网编辑
编辑最后更新 2024年11月28日,怎样解决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() {                        @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> 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中的死锁问题的方法了吗?如果想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

0