How to check whether there are Java thread deadlocks? Two methods are described below.
I Jconsole
Jconsole is a graphical interface tool provided by JDK. Using jconsole, a tool provided by JDK, you can open it by opening cmd and then entering jconsole.
Connect to the process you want to view.
Open the threads tab and click "detect deadlock" in the lower left corner.
jconsole will detect the thread causing deadlock in this thread. Click Select to view the details:
As can be seen from the above figure:
In Thread-1, it can be seen from the status that it wants to apply for Java lang. Object@35b4e829 This resource, but this resource is already owned by Thread-0, so it is blocked.
In Thread-0, it can be seen from the status that it wants to apply for Java lang. Object@2db8dc9 This resource, but this resource is already owned by Thread-1, so it is blocked.
Thread-1 has been waiting for Java lang. Object@35b4e829 Resource, and thread – 0 has been waiting for Java lang. Object@2db8dc9 Resources, so the two threads are deadlocked, causing a deadlock.
II Jstack
Jstack is a command line tool built into JDK. It is mainly used for thread Dump analysis.
1. Let's first use Jps to view the java process ID (or the ps command of Linux)
2. Take a look at the use of jstack
3.jstack outputs thread dump information to a file
The difference between with - l and without - l is as follows:
4. View the dump file and analyze it
One of the lines is at DeadThread Run (DeadThread.java:37), indicating that Thread-1 actually has a deadlock at line 37 of the DeadThread class, where at DeadThread.run(DeadThread.java:21) indicates that Thread-0 has a deadlock at line 21 of the DeadThread class. For detailed jstack dump file analysis, see: jstack and thread dump analysis - bijian1013 - blog Garden.
So as to locate the cause and specific location of the deadlock: Thread-0 obtains lock lock1, and then expects to obtain lock lock2 (line 20), but at this time, Thread-1 obtains lock lock2, and then expects to obtain lock lock2 (line 37), so the deadlock occurs.
public class DeadThread implements Runnable { public String username; public Object lock1 = new Object(); public Object lock2 = new Object(); @Override public void run() { // TODO Auto-generated method stub if (username.equals("a")) { synchronized (lock1) { try { System.out.println("username = " + username); System.out.println(Thread.currentThread().getName()); Thread.sleep(3000); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } synchronized (lock2) { System.out.println("Press lock1->lock2 Execute code in order"); } } } if (username.equals("b")) { synchronized (lock2) { try { System.out.println("username = " + username); System.out.println(Thread.currentThread().getName()); Thread.sleep(3000); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } synchronized (lock1) { System.out.println("Press lock2->lock1 Sequential execution code"); } } } } public void setFlag(String username) { this.username = username; } public static void main(String[] args) { DeadThread dt1 = new DeadThread(); dt1.setFlag("a"); Thread t1 = new Thread(dt1); t1.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } dt1.setFlag("b"); Thread t2 = new Thread(dt1); t2.start(); } }