当前位置: 首页 > 科技观察

谈谈死锁的四种故障排除工具!

时间:2023-03-20 23:22:39 科技观察

作者|王磊来源|Java中文社区(ID:javacn666)请联系授权(微信ID:GG_Stone)进程),都在等待对方停止执行获取系统资源,但双方都没有提前退出,就叫死锁。死锁示例下面我们来演示一下Java中最简单的死锁。我们创建两把锁和两个线程,让线程1先拥有锁A,1s后尝试获取锁B。同时启动线程2,先让它拥有锁B,1s后尝试获取锁A。这时候就会出现等待对方释放锁的情况,就会出现死锁问题。具体代码如下:publicclassDeadLockExample{publicstaticvoidmain(String[]args){ObjectlockA=newObject();//创建锁AObjectlockB=newObject();//创建锁B//创建线程1Threadt1=newThread(newRunnable(){@Overridepublicvoidrun(){//先获取锁Asynchronized(lockA){System.out.println("Thread1:GetlockA!");try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}//尝试获取锁BSystem.out.println("线程1:等待获取B...");synchronized(lockB){System.out.println("线程1:获取锁B!");}}}});t1.start();//运行线程//创建线程2Threadt2=newThread(newRunnable(){@Overridepublicvoidrun(){//先获取锁Bsynchronized(lockB){System.out.println("Thread2:GetlockB!");try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}//尝试获取锁ASystem.out.println("Thread2:等待获取A...");synchronized(lockA){System.out.println("线程2:获取锁A!");}}}});t2.start();//runningthread}}以上程序的执行结果如下:从上面的结果可以看出,线程1和线程2都在等待对方释放锁,这就造成了死锁问题。死锁的成因通过上面的例子,我们可以得出结论,需要满足以下四个条件才能产生死锁:互斥条件:指计算单元(进程、线程或协程)对allocatedresource,也就是说某个锁资源只能在一定时间内使用。可以被一个运算单元占用。请求和保持条件:指操作单元至少保留了一个资源,但又提出新的资源请求,该资源已被其他操作单元占用。坚持,稍等。不可剥夺条件:指计算单元获得的资源,在用完之前不能被剥夺。循环等待条件:发生死锁时,必然存在计算单元和资源的循环链,即计算单元在等待另一个计算单元占用的资源,而另一方在等待自己占用的资源,导致循环等待案例。只有同时满足以上4个条件,才会出现死锁问题。死锁排查如果程序出现死锁问题,可以通过以下4种解决方案中的任意一种进行分析排查。方案一:jstack在我们使用jstack之前,我们需要通过jps获取运行程序的进程ID。使用方法如下:“jps-l”可以查询本机所有Java程序。jps(JavaVirtualMachineProcessStatusTool)是一个Java提供的显示当前所有Java进程的pid的命令,适用于在linux/unix/windows平台上查看当前Java进程的一些简单情况,“-l”为用于输出进程pid和运行程序的全路径名(包名和类名)。有了进程ID(PID),我们就可以使用“jstack-lPID”来查找死锁问题,如下图:jstack用于生成Java虚拟机当前时刻的线程快照,“-l”表示长列表(long)打印关于锁的附加信息。PS:可以使用jstack-help查看更多命令说明。方案二:jconsole使用jconsole需要打开JDK的bin目录,找到jconsole双击打开,如下图:然后选择要调试的程序,如下图:然后点击连接进入,选择“不安全连接”进入监控首页,如下图:然后切换到“线程”模块,点击“检测死锁”按钮,如下图:过段时间会检测到死锁的相关信息,如下图:方案三:jvisualvmjvisualvm也在JDK的bin目录下,同样是双击打开:几秒后,所有本地Java程序都会出现在jvisualvm中,如下图:双击选择要调试的程序:单机鼠标进入“线程”模块,如下图:从中可以看出上图,当我们切换到线程一栏时,死锁信息will会直接显示出来,然后点击“ThreadDump”生成死锁的详细信息,如下图:解决方案4:jmcjmc是OracleJavaMissionControl的缩写,是一套管理、监控的工具、分析和故障排除Java程序。同样在JDK的bin目录下,同样是双击启动,如下图:jmc主页信息如下:选择要检查的程序后,右键“StartJMXConsole”可以查看程序的详细信息,如下图:然后点击“Thread”,勾选“DeadlockDetection”,可以找到死锁和死锁的详细信息,如下图:总结死锁是因为两个或者多个计算单元互相等待对方停止Execution获取系统资源,但是任何一方都没有提前退出,所以就出现了死锁。死锁排查工具有四种:jstackjconsolejvisualvmjmc考虑到易用性和性能,推荐使用jconsole或者jvisualvm排查死锁。【小编推荐】19岁“神童”自制CPU!1200个晶体管,手工打造马斯克发布机器人,“钢铁侠”!特斯拉推出全球超快AI电脑Windows11来了,它们还活着!盘点老牌长青小软件Windows11预览更新!带你看Windows11内置新功能,千万别用5G,非5G手机为何不买