Troubleshooting: using control + break to solve thread deadlock

brief introduction

If we encounter thread deadlock in the program, how to solve it?

This article will start from a practical example and uncover the veil of Java problem solving step by step.

Deadlock code

People who have written Java multithreaded programs should know that a very important thing in multithreading is state synchronization, but in the process of state synchronization, carelessness may lead to deadlock.

One of the simplest deadlock situations is that thread1 occupies resource 1 and then has to obtain resource 2 When thread2 occupies resource 2, it has to obtain resource 1.

For example:

public class TestDeadLock {
    public static Object lock1= new Object();
    public static Object lock2= new Object();
    public static void main(String[] args) {
        Runnable runnable1= ()-> {
            System.out.println("in lock1");
            synchronized(lock1){
                System.out.println("Lock1 lock obj1");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(lock2){
                    System.out.println("Lock1 lock obj2");
                }
            }
        };

        Runnable runnable2= ()-> {
            System.out.println("in lock2");
            synchronized(lock2){
                System.out.println("Lock2 lock obj2");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(lock1){
                    System.out.println("Lock2 lock obj1");
                }
            }
        };

        Thread a = new Thread(runnable1);
        Thread b = new Thread(runnable2);
        a.start();
        b.start();
    }
}

We run the above code:

in lock1
Lock1 lock obj1
in lock2
Lock2 lock obj2

When the lock cycle waiting is sent, the program cannot be executed, and a deadlock is sent.

Control + break command

When the code is very simple, we can easily analyze the cause of deadlock, but if it is in a very large online project, it is not so easy to analyze the code.

How?

Today, I'll teach you a method to use the control + break command.

Control + break means control + backslash in Linux, and the control + break button in windows.

Of course, there is a more general way to use:

Kill - quit PID command.

We use the JPS command to obtain the process ID of executing the Java program, and then execute the kill - quit command.

After execution, we will find that the running java process will output some additional logs, which are the key factor for us to find deadlock.

Note that this kill command does not terminate the program.

There are a lot of output contents. We will explain them part by part.

Full thread dump

The first part of the log is full thread dump, which contains the status information of all threads in the JVM.

Let's look at two key thread information in our code:

"Thread-0" #13 prio=5 os_prio=31 cpu=4.86ms elapsed=230.16s tid=0x00007fc926061800 nid=0x6403 waiting for monitor entry  [0x0000700008d6a000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.flydean.TestDeadLock.lambda$main$0(TestDeadLock.java:21)
	- waiting to lock <0x0000000787e868f0> (a java.lang.Object)
	- locked <0x0000000787e868e0> (a java.lang.Object)
	at com.flydean.TestDeadLock$$Lambda$14/0x0000000800b69840.run(UnkNown Source)
	at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)

"Thread-1" #14 prio=5 os_prio=31 cpu=4.32ms elapsed=230.16s tid=0x00007fc924869800 nid=0x6603 waiting for monitor entry  [0x0000700008e6d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.flydean.TestDeadLock.lambda$main$1(TestDeadLock.java:36)
	- waiting to lock <0x0000000787e868e0> (a java.lang.Object)
	- locked <0x0000000787e868f0> (a java.lang.Object)
	at com.flydean.TestDeadLock$$Lambda$15/0x0000000800b69c40.run(UnkNown Source)
	at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)

The above output lists the thread name, thread priority, CPU time, whether it is a daemon thread, thread ID, thread status and other useful information.

Seeing the above output, we can see that both threads are in blocked state and are waiting for object monitor.

Remember several states of threads? Let's review it again.

Deadlock detection

The next part is the deadlock detection we are most concerned about.

Found one Java-level deadlock:
=============================
"Thread-0":
  waiting to lock monitor 0x00007fc926807e00 (object 0x0000000787e868f0,a java.lang.Object),which is held by "Thread-1"

"Thread-1":
  waiting to lock monitor 0x00007fc926807f00 (object 0x0000000787e868e0,which is held by "Thread-0"

Java stack information for the threads listed above:
===================================================
"Thread-0":
	at com.flydean.TestDeadLock.lambda$main$0(TestDeadLock.java:21)
	- waiting to lock <0x0000000787e868f0> (a java.lang.Object)
	- locked <0x0000000787e868e0> (a java.lang.Object)
	at com.flydean.TestDeadLock$$Lambda$14/0x0000000800b69840.run(UnkNown Source)
	at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)
"Thread-1":
	at com.flydean.TestDeadLock.lambda$main$1(TestDeadLock.java:36)
	- waiting to lock <0x0000000787e868e0> (a java.lang.Object)
	- locked <0x0000000787e868f0> (a java.lang.Object)
	at com.flydean.TestDeadLock$$Lambda$15/0x0000000800b69c40.run(UnkNown Source)
	at java.lang.Thread.run(java.base@14.0.1/Thread.java:832)

Found 1 deadlock.

We can clearly see from the above log that two threads have obtained the locks required by each other, resulting in deadlock.

At the same time, the information of thread stack is listed in detail for our analysis.

Heap information

The last part is the statistics of heap:

Heap
 garbage-first heap   total 133120K,used 3888K [0x0000000780000000,0x0000000800000000)
  region size 1024K,4 young (4096K),0 survivors (0K)
 Metaspace       used 1122K,capacity 4569K,committed 4864K,reserved 1056768K
  class space    used 108K,capacity 412K,committed 512K,reserved 1048576K
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>