Java Management Extension provides a powerful APIs to find out all details about the JVM. Today we will write a simple program to find out dead lock in java using JMX API. The intention of this program is only to find the dead lock, the program which is used to create the dead lock should not be used any application in any circumstances. However DeadlockFinderThread shall be used in the development environment to find out the dead lock.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
package com.ourownjava.corejava.thread; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; /** * * @author ourownjava.com * @date 13th, August 2011 * * How to find dead lock in java? * */ public class DeadlockExample { public static void main(final String args[]){ final Thread deadlockFinder = new DeadlockFinderThread(); deadlockFinder.setDaemon(true); deadlockFinder.start(); final String resource1 = new String("apple"); final String resource2 = new String("orange"); final Thread thread1 = new Thread(new WorkerThread2(resource1, resource2)); thread1.setName("thread1"); thread1.start(); final Thread thread2 = new Thread(new WorkerThread3(resource1, resource2)); thread2.setName("thread2"); thread2.start(); } } class DeadlockFinderThread extends Thread{ @Override public void run(){ while(true){ final long[] ids = ManagementFactory.getThreadMXBean() .findDeadlockedThreads(); if(null != ids){ final ThreadInfo[] threadInfo = ManagementFactory .getThreadMXBean().getThreadInfo(ids); for(final ThreadInfo info : threadInfo){ System.out.println(info.getThreadName() +" is waiting for "+info.getLockOwnerName()); } } } } } class WorkerThread2 implements Runnable{ String resource1; String resource2; public WorkerThread2(final String resource1, final String resource2){ this.resource1 = resource1; this.resource2 = resource2; } @Override public void run(){ System.out.println("WorkerThread.run()"); synchronized (resource1) { System.out.println("got lock on resource1.. now process resource1"); try { // I am simulating the process using one second sleep Thread.sleep(1000); } catch (final InterruptedException e) { e.printStackTrace(); } synchronized (resource2) { System.out.println("got lock on resource2"); } } } } class WorkerThread3 implements Runnable{ String resource1; String resource2; public WorkerThread3(final String resource1, final String resource2){ this.resource1 = resource1; this.resource2 = resource2; } @Override public void run() { System.out.println("WorkerThread1.run()"); synchronized (resource2) { System.out.println("got lock on resource2.. now process resource1"); try { // I am simulating the process using one second sleep Thread.sleep(1000); } catch (final InterruptedException e) { e.printStackTrace(); } synchronized (resource1) { System.out.println("got lock on resource1"); } } } } |
Console output.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/local/opt/java com.ourownjava.corejava.thread.DeadlockExample WorkerThread.run() got lock on resource1.. now process resource1 WorkerThread1.run() got lock on resource2.. now process resource1 thread2 is waiting for thread1 thread1 is waiting for thread2 thread2 is waiting for thread1 thread1 is waiting for thread2 thread2 is waiting for thread1 thread1 is waiting for thread2 thread2 is waiting for thread1 |