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

面试惊喜:死锁的排查工具有哪些?

时间:2023-03-23 10:45:11 科技观察

死锁(DeadLock)是指两个或多个计算单元(进程、线程或协程),都在等待对方释放资源,但没有人提出释放资源,从而造成一种阻塞的现象是称为死锁。例如,线程1在拥有锁A的情况下尝试获取锁B,线程2在拥有锁B的情况下尝试获取锁A,这样双方就进入了相互阻塞等待的情况,如下图所示:deadlock代码实现如下:importjava.util.concurrent.TimeUnit;publicclassDeadLockTest{publicstaticvoidmain(String[]args){ObjectlockA=newObject();对象锁B=新对象();//创建线程1Threadt1=newThread(()->{//1.占用锁Asynchronized(lockA){System.out.println("Thread1:GetlockA.");//休眠1s(让线程2有时间启动占用锁B)try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}//2.获取线程2的锁Bsynchronized(lockB){System.out.println("线程1:获得了锁B。");}}});t1.start();//创建线程2Threadt2=newThread(()->{//1.占用锁Bsynchronized(lockB){System.out.println("Thread2:获取锁B.");//休眠1s(保证线程1有足够的时间获取锁A)try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}//2.获取线程1的锁Asynchronized(lockA){System.out.println("Thread2:getlockA.");}}});t2.start();}}执行上面的程序结果如下图所示:从上面的结果可以看出,线程1和线程2都在等待对方释放锁,这就造成了死锁问题,死锁应该怎么处理checked?死锁检查工具一共检查死锁一共有4个工具:jstackjconsolejvisualvmjmc接下来我们一一来看。排错工具一: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双击打开,如下图:然后选择要调试的程序,如下图:然后点击Connect进入,选择“UnsafeConnection”进入Monitor首页,如下图:然后切换到“Thread”模块,点击“DetectDeadlock”按钮,如下图:稍等片刻,就会检测到死锁的相关信息,如下图:排查工具3:jvisualvmjvisualvm也在JDK的bin目录下,同样是双击打开:几秒后,所有本地Java程序会出现在jvisualvm中,如下图:双击选择要调试的程序:点击进入“Thread”模块,如下图:从上图可以看出,当我们切换到线程列时,死锁信息will会直接显示,然后点击“ThreadDump”生成死锁的详细信息,如下图:故障排除工具4:jmcjmc是OracleJavaMissionControl的缩写,是一个管理、监控的工具套件、分析和故障排除Java程序。同样在JDK的bin目录下,同样是双击启动,如下图:jmc主页信息如下:选择要检查的程序后,右键“StartJMXConsole”可以查看程序的详细信息,如下图:然后点击“Thread”,勾选“DeadlockDetection”,可以找到deadlock和deadlock的详细信息,如下图:有4个各种死锁排查工具总结:jstack、jconsole、jvisualvm、jmc,从易用性和性能上来说,推荐使用jconsole或者jvisualvm来排查死锁。