博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java虚拟机工具之堆栈跟踪工具jstack检测死锁
阅读量:4097 次
发布时间:2019-05-25

本文共 8358 字,大约阅读时间需要 27 分钟。

jstack是一个很实用的工具,不仅能定位到死循环的位置,还能找到死锁的位置,这个工具对我们直接在生产机上定位错误带来了极大的方便,尤其是那些不容易复现的错误。

首先呢,先写一个能产生死锁的代码。代码逻辑很简单,咱就产生两个线程,两个线程分别执行加锁与放锁两个动作,啥时候产生死锁呢,就是在两个线程都释放锁以后,又同时加锁,于是互相僵持,互相等待,产生死锁。

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Created by Kevin on 11/4/16. */class MultiThread implements Runnable{    private Object o1;    private Object o2;    private int flag;    public MultiThread(Object o1, Object o2, int flag) {        this.o1 = o1;        this.o2 = o2;        this.flag = flag;    }    public void task1() throws InterruptedException{        synchronized (o1){            synchronized (o2){                System.out.println(Thread.currentThread().getName());            }        }    }    public void task2() throws InterruptedException{        synchronized (o2){            Thread.yield();            synchronized (o1) {                System.out.println(Thread.currentThread().getName());            }        }    }    @Override    public void run() {        while (true) {            try {                if (this.flag == 1) {                    this.task1();                } else {                    this.task2();                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}public class DeadLock {
public static void main(String[] args){ Object o1 = new Object(); Object o2 = new Object(); ExecutorService executorService = Executors.newFixedThreadPool(10); for (int flag = 0; flag < 2; flag++) { executorService.execute(new MultiThread(o1, o2, flag)); } }}

运行代码,你会发现控制台过一会儿就不动了,但是程序运行没有终止,下面用jstack看看到底啥问题。

首先要找到该进程的pid

$ jps11523 Main27894 AppMain27912 Launcher27933 Jps12046 JConsole

然后可以看到pid=27894,辣么用jstack查看一下27894:

$ jstack 278942016-11-07 14:59:55Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode):"Attach Listener" #13 daemon prio=9 os_prio=0 tid=0x00007f5660001000 nid=0x6d3b runnable [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"DestroyJavaVM" #12 prio=5 os_prio=0 tid=0x00007f569800a800 nid=0x6cf7 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"pool-1-thread-2" #11 prio=5 os_prio=0 tid=0x00007f5698156800 nid=0x6d07 waiting for monitor entry [0x00007f5684175000]   java.lang.Thread.State: BLOCKED (on object monitor)    at MultiThread.task1(DeadLock.java:21)    - waiting to lock <0x00000000ec215b70> (a java.lang.Object)    - locked <0x00000000ec215b60> (a java.lang.Object)    at MultiThread.run(DeadLock.java:41)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at java.lang.Thread.run(Thread.java:745)"pool-1-thread-1" #10 prio=5 os_prio=0 tid=0x00007f5698155000 nid=0x6d06 waiting for monitor entry [0x00007f5684276000]   java.lang.Thread.State: BLOCKED (on object monitor)    at MultiThread.task2(DeadLock.java:30)    - waiting to lock <0x00000000ec215b60> (a java.lang.Object)    - locked <0x00000000ec215b70> (a java.lang.Object)    at MultiThread.run(DeadLock.java:43)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at java.lang.Thread.run(Thread.java:745)"Monitor Ctrl-Break" #9 daemon prio=5 os_prio=0 tid=0x00007f5698152800 nid=0x6d05 runnable [0x00007f5684377000]   java.lang.Thread.State: RUNNABLE    at java.net.PlainSocketImpl.socketAccept(Native Method)    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)    at java.net.ServerSocket.implAccept(ServerSocket.java:545)    at java.net.ServerSocket.accept(ServerSocket.java:513)    at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:90)    at java.lang.Thread.run(Thread.java:745)"Service Thread" #8 daemon prio=9 os_prio=0 tid=0x00007f56980da800 nid=0x6d03 runnable [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"C1 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f56980bd000 nid=0x6d02 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f56980bb800 nid=0x6d01 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f56980b8800 nid=0x6d00 waiting on condition [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f56980b7000 nid=0x6cff runnable [0x0000000000000000]   java.lang.Thread.State: RUNNABLE"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f5698084000 nid=0x6cfe in Object.wait() [0x00007f5685682000]   java.lang.Thread.State: WAITING (on object monitor)    at java.lang.Object.wait(Native Method)    - waiting on <0x00000000ec188ee0> (a java.lang.ref.ReferenceQueue$Lock)    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)    - locked <0x00000000ec188ee0> (a java.lang.ref.ReferenceQueue$Lock)    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f569807f800 nid=0x6cfd in Object.wait() [0x00007f5685783000]   java.lang.Thread.State: WAITING (on object monitor)    at java.lang.Object.wait(Native Method)    - waiting on <0x00000000ec186b50> (a java.lang.ref.Reference$Lock)    at java.lang.Object.wait(Object.java:502)    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)    - locked <0x00000000ec186b50> (a java.lang.ref.Reference$Lock)    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)"VM Thread" os_prio=0 tid=0x00007f5698078000 nid=0x6cfc runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f569801f800 nid=0x6cf8 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f5698021000 nid=0x6cf9 runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f5698023000 nid=0x6cfa runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f5698024800 nid=0x6cfb runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f56980dd000 nid=0x6d04 waiting on condition JNI global references: 15Found one Java-level deadlock:============================="pool-1-thread-2":  waiting to lock monitor 0x00007f56680062c8 (object 0x00000000ec215b70, a java.lang.Object),  which is held by "pool-1-thread-1""pool-1-thread-1":  waiting to lock monitor 0x00007f5668004e28 (object 0x00000000ec215b60, a java.lang.Object),  which is held by "pool-1-thread-2"Java stack information for the threads listed above:==================================================="pool-1-thread-2":    at MultiThread.task1(DeadLock.java:21)    - waiting to lock <0x00000000ec215b70> (a java.lang.Object)    - locked <0x00000000ec215b60> (a java.lang.Object)    at MultiThread.run(DeadLock.java:41)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at java.lang.Thread.run(Thread.java:745)"pool-1-thread-1":    at MultiThread.task2(DeadLock.java:30)    - waiting to lock <0x00000000ec215b60> (a java.lang.Object)    - locked <0x00000000ec215b70> (a java.lang.Object)    at MultiThread.run(DeadLock.java:43)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at java.lang.Thread.run(Thread.java:745)Found 1 deadlock.

看到没,其中有一段长这个模样:

Found one Java-level deadlock:============================="pool-1-thread-2":  waiting to lock monitor 0x00007f56680062c8 (object 0x00000000ec215b70, a java.lang.Object),  which is held by "pool-1-thread-1""pool-1-thread-1":  waiting to lock monitor 0x00007f5668004e28 (object 0x00000000ec215b60, a java.lang.Object),  which is held by "pool-1-thread-2"Java stack information for the threads listed above:==================================================="pool-1-thread-2":    at MultiThread.task1(DeadLock.java:21)    ......    at MultiThread.run(DeadLock.java:41)    ......    at MultiThread.task2(DeadLock.java:30)    ......    at MultiThread.run(DeadLock.java:43)    ......Found 1 deadlock.

人家说了这里有死锁,哪个文件,第几行都告你了,剩下的就自己去改吧。

转载地址:http://izhii.baihongyu.com/

你可能感兴趣的文章
inet_ntoa、 inet_aton、inet_addr
查看>>
用模板写单链表
查看>>
用模板写单链表
查看>>
链表各类操作详解
查看>>
C++实现 简单 单链表
查看>>
数据结构之单链表——C++模板类实现
查看>>
Linux的SOCKET编程 简单演示
查看>>
正则匹配函数
查看>>
Linux并发服务器编程之多线程并发服务器
查看>>
聊聊gcc参数中的-I, -L和-l
查看>>
[C++基础]034_C++模板编程里的主版本模板类、全特化、偏特化(C++ Type Traits)
查看>>
C语言内存检测
查看>>
Linux epoll模型
查看>>
Linux select TCP并发服务器与客户端编程
查看>>
Linux系统编程——线程池
查看>>
基于Visual C++2013拆解世界五百强面试题--题5-自己实现strstr
查看>>
Linux 线程信号量同步
查看>>
C++静态成员函数访问非静态成员的几种方法
查看>>
类中的静态成员函数访问非静态成员变量
查看>>
C++学习之普通函数指针与成员函数指针
查看>>