死锁概念:
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
-------- 百度百科
死锁的规范定义:
集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。
-------- 百度百科
代码示例:
/** * java死锁示例 */ public class DeadLock { private static final Object OBJECT1 = new Object(); private static final Object OBJECT2 = new Object(); public static void main(String[] args) { new Thread(() -> { synchronized (OBJECT1) { try { // cpu执行太快,利用休眠触发死锁 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (OBJECT2) { System.out.println("OBJECT1获取到了OBJECT2的锁!"); } } }).start(); new Thread(() -> { synchronized (OBJECT2) { synchronized (OBJECT1) { System.out.println("OBJECT2获取到了OBJECT1的锁!"); } } }).start(); } }
查看死锁的方法:
方法一:jps + jstack
首先用jps查看进程id
Terminal:$ jps 1488 Launcher 1489 DeadLock 1490 Jps 1255
再用jstack 1489(进程id) 查看堆栈信息
Terminal:$ jstack 1489 Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007fdf0e80ed68 (object 0x000000076ac28c70, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007fdf0e8100a8 (object 0x000000076ac28c80, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at com.farstars.demo.DeadLock.lambda$main$1(DeadLock.java:29) - waiting to lock <0x000000076ac28c70> (a java.lang.Object) - locked <0x000000076ac28c80> (a java.lang.Object) at com.farstars.demo.DeadLock$$Lambda$2/2129789493.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Thread-0": at com.farstars.demo.DeadLock.lambda$main$0(DeadLock.java:21) - waiting to lock <0x000000076ac28c80> (a java.lang.Object) - locked <0x000000076ac28c70> (a java.lang.Object) at com.farstars.demo.DeadLock$$Lambda$1/1607521710.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock.
从上述堆栈信息中可以很明显的看到发生了死锁现象。
方法二:jconsole
命令行直接敲jconsole命令,使用自带的控制台查看死锁情况
这里选择本地进程中的死锁类即可,然后点击连接。
然后再点击线程这一栏,点击下方检测死锁。
这里也可以清晰的看到进程的死锁情况,Thread-0和Thread-1分别持有对方的锁。
总结:
非常简单的死锁代码示例,同时利用java自带的工具帮助我们确认是否发生死锁现象。