java deadlock, deadlock three ways to quickly find the code

Deadlock problem java program, if you do not understand the investigation process is helpless, today we find the deadlock in three ways.

Run the following codes

package com.jvm.visualvm;

/**
 * <a href="http://www.itsoku.com/archives">Java干货铺子,只生产干货,公众号:javacode2018</a>
 */
public class Demo4 {

    public static void main(String[] args) {
        User u1 = new User("u1");
        User u2 = new User("u2");
        Thread thread1 = new Thread(new SynAddRunalbe(u1, u2, 1, 2, true));
        thread1.setName("thread1");
        thread1.start();
        Thread thread2 = new Thread(new SynAddRunalbe(u1, u2, 2, 1, false));
        thread2.setName("thread2");
        thread2.start();
    }

    /**
     * 线程死锁等待演示
     */
    public static class SynAddRunalbe implements Runnable {
        User u1, u2;
        int a, b;
        boolean flag;

        public SynAddRunalbe(User u1, User u2, int a, int b, boolean flag) {
            this.u1 = u1;
            this.u2 = u2;
            this.a = a;
            this.b = b;
            this.flag = flag;
        }

        @Override
        public void run() {
            try {
                if (flag) {
                    synchronized (u1) {
                        Thread.sleep(100);
                        synchronized (u2) {
                            System.out.println(a + b);
                        }
                    }
                } else {
                    synchronized (u2) {
                        Thread.sleep(100);
                        synchronized (u1) {
                            System.out.println(a + b);
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class User {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public User(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
}

Program: thread1 holding the lock of u1, thread2 holding the lock of u2, thread1 waiting to acquire the lock u2, thread2 waiting to acquire the lock u1, need each other to obtain the locks was the other owners, resulting in a deadlock. It has been unable to end the program is running.

By jdk tool jps, jstack investigation deadlock

Command tool jps, jstack jdk are provided to facilitate the user to troubleshoot some of the problems the program. More detailed usage see the final document.

Step 1: Using jsp Find program

jps: a tool provided by jdk, you can view the running process java

C:\Users\Think>jps -l
5824 com.jvm.visualvm.Demo4

Step 2: Using jstack view the thread stack information

jstack: jdk provide a tool, you can view the process of java thread stack information. More detailed usage see the final document.

C:\Users\Think>jstack 5824
2019-06-04 15:34:37
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x0000000002cf4000 nid=0x9fd8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"thread2" #13 prio=5 os_prio=0 tid=0x000000002884d800 nid=0x40c4 waiting for monitor entry [0x00000000292ce000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.jvm.visualvm.Demo4$SynAddRunalbe.run(Demo4.java:49)
        - waiting to lock <0x00000007173d4178> (a com.jvm.visualvm.Demo4$User)
        - locked <0x00000007173d41b8> (a com.jvm.visualvm.Demo4$User)
        at java.lang.Thread.run(Thread.java:745)

"thread1" #12 prio=5 os_prio=0 tid=0x000000002885b800 nid=0x99c0 waiting for monitor entry [0x00000000291cf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.jvm.visualvm.Demo4$SynAddRunalbe.run(Demo4.java:42)
        - waiting to lock <0x00000007173d41b8> (a com.jvm.visualvm.Demo4$User)
        - locked <0x00000007173d4178> (a com.jvm.visualvm.Demo4$User)
        at java.lang.Thread.run(Thread.java:745)

"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x0000000027dd9000 nid=0x7f80 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x0000000027d80800 nid=0x3b94 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x0000000027d7c000 nid=0x4c7c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000027d7b000 nid=0x8f4c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000027d73000 nid=0x9094 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000027d0a800 nid=0x647c runnable [0x00000000282ce000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        - locked <0x0000000717449cd8> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        - locked <0x0000000717449cd8> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000027b61000 nid=0x7cf8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000027b5f800 nid=0x94f4 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000027af1800 nid=0x9960 in Object.wait() [0x0000000027fce000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x0000000717188ec8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x0000000717188ec8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000002deb000 nid=0xb2bc in Object.wait() [0x0000000027acf000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x0000000717186b68> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x0000000717186b68> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=2 tid=0x0000000025be9000 nid=0xaa90 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002d0a000 nid=0x3fc0 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002d0b800 nid=0x9cf8 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002d0d000 nid=0x51c runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002d0e800 nid=0x24d0 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002d12000 nid=0x618c runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002d13000 nid=0x5550 runnable

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002d16000 nid=0x8994 runnable

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002d17800 nid=0x39cc runnable

"VM Periodic Task Thread" os_prio=2 tid=0x0000000027dd9800 nid=0x5294 waiting on condition

JNI global references: 33


Found one Java-level deadlock:
=============================
"thread2":
  waiting to lock monitor 0x0000000028846468 (object 0x00000007173d4178, a com.jvm.visualvm.Demo4$User),
  which is held by "thread1"
"thread1":
  waiting to lock monitor 0x0000000025bf0bb8 (object 0x00000007173d41b8, a com.jvm.visualvm.Demo4$User),
  which is held by "thread2"

Java stack information for the threads listed above:
===================================================
"thread2":
        at com.jvm.visualvm.Demo4$SynAddRunalbe.run(Demo4.java:49)
        - waiting to lock <0x00000007173d4178> (a com.jvm.visualvm.Demo4$User)
        - locked <0x00000007173d41b8> (a com.jvm.visualvm.Demo4$User)
        at java.lang.Thread.run(Thread.java:745)
"thread1":
        at com.jvm.visualvm.Demo4$SynAddRunalbe.run(Demo4.java:42)
        - waiting to lock <0x00000007173d41b8> (a com.jvm.visualvm.Demo4$User)
        - locked <0x00000007173d4178> (a com.jvm.visualvm.Demo4$User)
        at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

From the top of the stack information we can find this content: " Found the Java One-Level deadlock ", indicates that the program was found in a deadlock, with more behind contains detailed information highlighted below:

Java stack information for the threads listed above:
===================================================
"thread2":
        at com.jvm.visualvm.Demo4$SynAddRunalbe.run(Demo4.java:49)
        - waiting to lock <0x00000007173d4178> (a com.jvm.visualvm.Demo4$User)
        - locked <0x00000007173d41b8> (a com.jvm.visualvm.Demo4$User)
        at java.lang.Thread.run(Thread.java:745)
"thread1":
        at com.jvm.visualvm.Demo4$SynAddRunalbe.run(Demo4.java:42)
        - waiting to lock <0x00000007173d41b8> (a com.jvm.visualvm.Demo4$User)
        - locked <0x00000007173d4178> (a com.jvm.visualvm.Demo4$User)
        at java.lang.Thread.run(Thread.java:745)

May deadlock in Demo4.java code is 49 lines and 42 lines, this time we will be able to optimize the code, solve the deadlock.

Jdk tool provided by jconsole investigation deadlock

jconsole: a visual tool jdk provided to facilitate the investigation process some of the problems, such as: Program memory overflow, deadlock and so on. More detailed usage see the final document.

jconsole located jdk bin directory

Step one: Open jconsole.exe

Here Insert Picture Description

We can see the program, click on the link.

Step two: Check the thread stack information in jconsole window

Here Insert Picture Description

Step three: the stack view deadlock information

Click on "Deadlock detection", you can see the deadlock message.

Here Insert Picture Description

Here Insert Picture Description

Deadlock can see the figure above detailed information, and similar information jstack.

Jdk tool provided by VisualVM investigation deadlock

VisualVM: jdk provided a very powerful troubleshooting java program issues a tool that can monitor the performance of the program, view the configuration information jvm heap snapshot, thread stack information. Regarded as an essential tool for program optimization.

工具位于jdk的bin目录中。

步骤一:打开VisualVM.exe

Here Insert Picture Description

步骤二:在visualvm中查看我们的目标程序

目标程序在visualvm左侧窗口中,双击即可打开。

Here Insert Picture Description

步骤三:切换到“线程”窗口

Here Insert Picture Description

步骤四:查看堆栈信息

在线程窗口中点击“线程Dump”按钮

Here Insert Picture Description

可以看到产生了一个线程堆栈快照

Here Insert Picture Description

线程堆栈快照的信息和jstack查看到的信息一样,即可发现死锁代码。

总结

程序中介绍了3中排查死锁的方法,使用到的都是jdk提供给我们的工具,这些工具对于我们优化程序来说,是非常好的,我们一定要掌握。

这些工具的使用可以查看:java虚拟机全集(31篇文章)

深入理解java虚拟机系列

  • 深入理解Java虚拟机笔记---内存区域
  • 深入理解Java虚拟机笔记---判断对象是否存活
  • 深入理解Java虚拟机笔记---垃圾收集算法
  • 深入理解Java虚拟机笔记---垃圾收集器
  • 深入理解Java虚拟机笔记---内存分配与回收策略
  • 深入理解Java虚拟机笔记---class类文件结构概述
  • 深入理解Java虚拟机笔记---class类文件魔数,版本,常量池
  • 深入理解Java虚拟机笔记---访问标志
  • 深入理解Java虚拟机笔记---类索引,父类索引,接口索引集合
  • 深入理解Java虚拟机笔记---字段表集合
  • 深入理解Java虚拟机笔记---方法表集合
  • 深入理解Java虚拟机笔记---属性表集合
  • 深入理解Java虚拟机笔记---引用类型和对象是否死亡
  • 深入理解Java虚拟机笔记---类加载时机
  • 深入理解Java虚拟机笔记---类加载过程
  • 深入理解Java虚拟机笔记---双亲委派模型
  • 深入理解Java虚拟机笔记---运行时栈帧结构
  • 深入理解Java虚拟机笔记---方法调用
  • 深入理解Java虚拟机笔记---内存模型
  • 深入理解Java虚拟机笔记---volatile变量的特殊规则
  • 深入理解Java虚拟机笔记---原子性、可见性、有序性
  • Hotspot JVM的常用选项
  • jvm新生代中为什么要有Survivor区,且必须是2个

jdk命令行工具系列

  • jdk command-line tools (1) - jps: Virtual Machine Process Status Tool
  • jdk command-line tools (2) - jstat: Virtual Machine statistics monitoring tool
  • jdk command-line tools (3) - jinfo: jvm configuration tool
  • jdk command-line tools (4) - jmap: java memory mapping tool
  • jdk command-line tools (5) - jhat: a snapshot of the virtual machine heap dump analysis tool
  • jdk command-line tools (6) - jstack: java stack trace tool

jdk visualization tools

  • JDK visualization tools (1) - JConsole: Java Monitoring and Management Console
  • JDK visualization tools (2) - jvisualvm: Combine troubleshooting tools

Guess you like

Origin www.cnblogs.com/itsoku123/p/10974157.html