目录

死锁的检测

Jstack命令

JConsole、jvisualvm工具

死锁的预防方法

充分考虑不同线程之前获得锁的顺序

超时放弃


死锁的检测

Jstack命令

生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。

jtack -l pid:

展示了  Found one Java-level deadlock:及具体的死锁信息展示;JAVA系列:死锁的检测与预防方法_java应用

 

JConsole、jvisualvm工具

Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。而且本身占用的服务器内存很小,甚至可以说几乎不消耗。

 

JAVA系列:死锁的检测与预防方法_死锁_02

JAVA系列:死锁的检测与预防方法_java应用_03

  死锁的预防方法

充分考虑不同线程之前获得锁的顺序

调整后前的调用关系: 

 

JAVA系列:死锁的检测与预防方法_java应用_04

 

调整后的调用关系: 

JAVA系列:死锁的检测与预防方法_java虚拟机_05

 

超时放弃

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

JAVA系列:死锁的检测与预防方法_死锁_06