例子程序:
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Hello world! */ public class App { public static void main(String[] args) throws InterruptedException { System.out.println("Hello World!"); ExecutorService executorService = Executors.newFixedThreadPool(2); byte[] i = new byte[0]; byte[] j = new byte[0]; final CountDownLatch countDownLatch = new CountDownLatch(2); executorService.execute(new DeadThread1(i, j,countDownLatch)); executorService.execute(new DeadThread2(i, j,countDownLatch)); countDownLatch.await(); System.out.println("done !!!"); } public static class DeadThread1 implements Runnable { private byte[] i; private byte[] j; private CountDownLatch countDownLatch; public DeadThread1(byte[] i, byte[] j, CountDownLatch countDownLatch) { this.i = i; this.j = j; this.countDownLatch = countDownLatch; } @Override public void run() { synchronized (i) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (j) { System.out.println(Thread.currentThread().getName() + "is running!!"); countDownLatch.countDown(); } } } } public static class DeadThread2 implements Runnable { private byte[] i; private byte[] j; private CountDownLatch countDownLatch; public DeadThread2(byte[] i, byte[] j, CountDownLatch countDownLatch) { this.i = i; this.j = j; this.countDownLatch = countDownLatch; } @Override public void run() { synchronized (j) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (i) { System.out.println(Thread.currentThread().getName() + "is running!!"); countDownLatch.countDown(); } } } } }
通过jps找到当前进程号:
guohaozhao116008@GUOHAOZHAO11600 /d $ jps 7448 RemoteMavenServer 6600 JConsole 6340 Jps 6272 7268 AppMain
通过jstack查看堆栈信息:
guohaozhao116008@GUOHAOZHAO11600 /d $ jstack Usage: jstack [-l] <pid> (to connect to running process) jstack -F [-m] [-l] <pid> (to connect to a hung process) jstack [-m] [-l] <executable> <core> (to connect to a core file) jstack [-m] [-l] [server_id@]<remote server IP or hostname> (to connect to a remote debug server) Options: -F to force a thread dump. Use when jstack <pid> does not respond (process is hung) -m to print both java and native frames (mixed mode) -l long listing. Prints additional information about locks -h or -help to print this help message guohaozhao116008@GUOHAOZHAO11600 /d $ jps 7448 RemoteMavenServer 6600 JConsole 6340 Jps 6272 7268 AppMain guohaozhao116008@GUOHAOZHAO11600 /d $ jstack -l 7268 2013-05-30 18:36:41 Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.14-b01 mixed mode): Found one Java-level deadlock: ============================= "pool-1-thread-2": waiting to lock monitor 0x000000000677c208 (object 0x00000000eafc3e18, a [B), which is held by "pool-1-thread-1" "pool-1-thread-1": waiting to lock monitor 0x0000000006771be8 (object 0x00000000eafc3e28, a [B), which is held by "pool-1-thread-2" Java stack information for the threads listed above: =================================================== "pool-1-thread-2": at com.sohu.suc.App$DeadThread2.run(App.java:74) - waiting to lock <0x00000000eafc3e18> (a [B) - locked <0x00000000eafc3e28> (a [B) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662) "pool-1-thread-1": at com.sohu.suc.App$DeadThread1.run(App.java:45) - waiting to lock <0x00000000eafc3e28> (a [B) - locked <0x00000000eafc3e18> (a [B) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662) Found 1 deadlock.
可以看到:
这里发生了死锁。
使用图形工具 jconsole 同样可以检测到: