Several tools to detect deadlocks: JStack, JConsole, JVisualVM, ThreadMXBean

Deadlock is a problem that must be avoided in development. It will cause threads to fail to run and function problems. Here are four ways to locate deadlock.

1. Deadlock example

First, let’s look at a simple deadlock example

public class SynchronizedTest {

	public static void main(String[] args) throws InterruptedException {
		DealThread t1 = new DealThread();
		t1.setFlag("a");
		Thread thread1 = new Thread(t1);
		thread1.start();
		
		Thread.sleep(1000);
		
		t1.setFlag("b");
		Thread thread2 = new Thread(t1);
		thread2.start();
	}
	
	static class DealThread implements Runnable{
		public String username;
		public Object lock1 = new Object();
		public Object lock2 = new Object();
		public void setFlag(String username) {
			this.username = username;
		}
		
		@Override
		public void run() {
			if("a".equals(username)) {
				synchronized (lock1) {
					try {
						System.out.println("username= " + username);
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					synchronized(lock2) {
						System.out.println("按lock1->lock2代码顺序执行了");
					}
				}
			}
			if("b".equals(username)) {
				synchronized (lock2) {
					try {
						System.out.println("username= " + username);
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					synchronized(lock1) {
						System.out.println("按lock2->lock1代码顺序执行了");
					}
				}
			}
		}
	}
}

2.JStack

JStack is a command line tool that comes with JDK, mainly used for thread Dump analysis. The Dump file is a memory image of the thread, and it saves the execution status information of the process. Its location is in the JAVA_HOME/bin directory. It is not a graphical interface, so it cannot be opened by double-clicking.
First open the CMD command line, execute the jps command, view the Java process information, find out the number of the Java process to be debugged, which is pid, here is 12980,
Insert picture description here
execute jstack -l pid, -l parameters can print out the lock related information, if It is a real project that may print a lot of information. We can use the jstack -l pid> D:deal_thread.log command to print all the information to the deal_thread.log file.
There are many print results, only information about deadlocks is intercepted

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

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.morlia.platform.synchronizedtest.SynchronizedTest$DealThread.run(SynchronizedTest.java:69)
        - waiting to lock <0x00000000d5cf9808> (a java.lang.Object)
        - locked <0x00000000d5cf9818> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)
"Thread-0":
        at com.morlia.platform.synchronizedtest.SynchronizedTest$DealThread.run(SynchronizedTest.java:55)
        - waiting to lock <0x00000000d5cf9818> (a java.lang.Object)
        - locked <0x00000000d5cf9808> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

Found 1 deadlock.

At this point, it can be seen from the printed information that the Thread-0 and Thread-1 threads are deadlocked in the run method.

3.JConsole

JConsole is a virtual machine monitoring tool that comes with the JDK. Its location is in the JAVA_HOME/bin directory. After double-clicking to open it, select the thread that may deadlock and click Connect.
Insert picture description here
After entering the monitoring page, click on the thread first, and then click on the detection deadlock in the lower left corner.
Insert picture description here
If a deadlock occurs, the deadlock thread information will appear in the deadlock column.
Insert picture description here
This information is similar to the information printed by jstack

4.JVisualVM

JVisualVM is a very powerful tool for troubleshooting Java programs provided by jdk, which can monitor program performance, view jvm configuration information, heap snapshots, and thread stack information. It is an essential tool for program optimization. The tool is located in the bin directory of the JDK and is also a graphical interface, which can be opened directly by double-clicking.
Insert picture description here
Select the process you need to see on the left, click the process tab on the right, and then click the thread tab. At this time, we can see a red letter stating that a deadlock has been detected, so we click Thread Dump to get more information.
At this time, it will appear threaddump page, the above information is the information of the dump file.
Insert picture description here

5.ThreadMXBean

Sometimes, we want the program to find the deadlock on its own, instead of needing us to find it. Java provides such tool classes.
Sample code:

public class SynchronizedTest {

	public static void main(String[] args) throws InterruptedException {
		DealThread t1 = new DealThread();
		t1.setFlag("a");
		Thread thread1 = new Thread(t1);
		thread1.start();
		
		Thread.sleep(1000);
		
		t1.setFlag("b");
		Thread thread2 = new Thread(t1);
		thread2.start();
		
		Thread.sleep(4000);
		
		//获取xbean实例
		ThreadMXBean mBean = ManagementFactory.getThreadMXBean();
		//获取死锁的线程ID
		long[] dealThreads = mBean.findDeadlockedThreads();
		//遍历
		for(long pid : dealThreads) {
			//获取线程信息
			ThreadInfo threadInfo = mBean.getThreadInfo(pid);
			System.out.println(threadInfo);
		}
	}
	
	static class DealThread implements Runnable{
		public String username;
		public Object lock1 = new Object();
		public Object lock2 = new Object();
		public void setFlag(String username) {
			this.username = username;
		}
		
		@Override
		public void run() {
			if("a".equals(username)) {
				synchronized (lock1) {
					try {
						System.out.println("username= " + username);
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					synchronized(lock2) {
						System.out.println("按lock1->lock2代码顺序执行了");
					}
				}
			}
			if("b".equals(username)) {
				synchronized (lock2) {
					try {
						System.out.println("username= " + username);
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					synchronized(lock1) {
						System.out.println("按lock2->lock1代码顺序执行了");
					}
				}
			}
		}
	}
}

operation result

username= a
username= b
"Thread-1" Id=11 BLOCKED on java.lang.Object@15db9742 owned by "Thread-0" Id=10
"Thread-0" Id=10 BLOCKED on java.lang.Object@6d06d69c owned by "Thread-1" Id=11

Detecting deadlocks and obtaining stack information are more performance-consuming operations and cannot be used frequently.
Deadlock is a bug in program design. When designing a program, avoid both parties holding each other's locks. As long as they wait for each other to release the lock, deadlock may occur.

Guess you like

Origin blog.csdn.net/d303577562/article/details/109225983