• jstack的使用


    jstack的使用

    有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增 高了、出现了死锁、死循环等,我们该如何分析呢?
    由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要 看下jvm的内部线程的执行情况,然后再进行分析查找出原因。
    这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程情况进 行快照,并且打印出来

    E:accpY2JVM>jstack 17656
    2020-03-03 16:54:24
    Full thread dump Java HotSpot(TM) Client VM (25.73-b02 mixed mode):
    
    "http-bio-8080-exec-6" #34 daemon prio=5 os_prio=0 tid=0x15535c00 nid=0x33ac waiting on condition [0x16f2f000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x0a270340> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-exec-5" #33 daemon prio=5 os_prio=0 tid=0x15535800 nid=0x27d0 waiting on condition [0x16e9f000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x0a270340> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-exec-4" #32 daemon prio=5 os_prio=0 tid=0x15538400 nid=0xa2c waiting on condition [0x16e0f000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x0a270340> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-exec-3" #31 daemon prio=5 os_prio=0 tid=0x15535000 nid=0x4bf4 waiting on condition [0x16d7f000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x0a270340> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-exec-2" #30 daemon prio=5 os_prio=0 tid=0x15537400 nid=0x4010 waiting on condition [0x16cef000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x0a270340> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-exec-1" #29 daemon prio=5 os_prio=0 tid=0x15537000 nid=0x2478 waiting on condition [0x1635f000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x0a270340> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)
            at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:745)
    
    "ajp-bio-8009-AsyncTimeout" #26 daemon prio=5 os_prio=0 tid=0x15537c00 nid=0x3ddc waiting on condition [0x162cf000]
       java.lang.Thread.State: TIMED_WAITING (sleeping)
            at java.lang.Thread.sleep(Native Method)
            at org.apache.tomcat.util.net.JIoEndpoint$AsyncTimeout.run(JIoEndpoint.java:152)
            at java.lang.Thread.run(Thread.java:745)
    
    "ajp-bio-8009-Acceptor-0" #25 daemon prio=5 os_prio=0 tid=0x15536800 nid=0x51a0 runnable [0x1623f000]
       java.lang.Thread.State: RUNNABLE
            at java.net.DualStackPlainSocketImpl.accept0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
            at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
            - locked <0x0a1352a8> (a java.net.SocksSocketImpl)
            at java.net.ServerSocket.implAccept(ServerSocket.java:545)
            at java.net.ServerSocket.accept(ServerSocket.java:513)
            at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60)
            at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:222)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-AsyncTimeout" #24 daemon prio=5 os_prio=0 tid=0x15538800 nid=0x2390 waiting on condition [0x161af000]
       java.lang.Thread.State: TIMED_WAITING (sleeping)
            at java.lang.Thread.sleep(Native Method)
            at org.apache.tomcat.util.net.JIoEndpoint$AsyncTimeout.run(JIoEndpoint.java:152)
            at java.lang.Thread.run(Thread.java:745)
    
    "http-bio-8080-Acceptor-0" #23 daemon prio=5 os_prio=0 tid=0x154e4000 nid=0x3d3c runnable [0x1611f000]
       java.lang.Thread.State: RUNNABLE
            at java.net.DualStackPlainSocketImpl.accept0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
            at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
            - locked <0x0a135390> (a java.net.SocksSocketImpl)
            at java.net.ServerSocket.implAccept(ServerSocket.java:545)
            at java.net.ServerSocket.accept(ServerSocket.java:513)
            at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60)
            at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:222)
            at java.lang.Thread.run(Thread.java:745)
    
    "ContainerBackgroundProcessor[StandardEngine[Catalina]]" #22 daemon prio=5 os_prio=0 tid=0x154e3c00 nid=0x1774 waiting on condition [0x1608f000]
       java.lang.Thread.State: TIMED_WAITING (sleeping)
            at java.lang.Thread.sleep(Native Method)
            at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1512)
            at java.lang.Thread.run(Thread.java:745)
    
    "GC Daemon" #18 daemon prio=2 os_prio=-2 tid=0x15484800 nid=0x4e2c in Object.wait() [0x15e6f000]
       java.lang.Thread.State: TIMED_WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x0a0dd158> (a sun.misc.GC$LatencyLock)
            at sun.misc.GC$Daemon.run(GC.java:117)
            - locked <0x0a0dd158> (a sun.misc.GC$LatencyLock)
    
    "RMI Scheduler(0)" #14 daemon prio=5 os_prio=0 tid=0x152b4c00 nid=0x617c waiting on condition [0x15aef000]
       java.lang.Thread.State: WAITING (parking)
            at sun.misc.Unsafe.park(Native Method)
            - parking to wait for  <0x09dbc780> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
            at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
            at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
            at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
            at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
            at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            at java.lang.Thread.run(Thread.java:745)
    
    "RMI TCP Accept-0" #12 daemon prio=5 os_prio=0 tid=0x151ac400 nid=0x252c runnable [0x1583f000]
       java.lang.Thread.State: RUNNABLE
            at java.net.DualStackPlainSocketImpl.accept0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
            at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
            - locked <0x09eb9b28> (a java.net.SocksSocketImpl)
            at java.net.ServerSocket.implAccept(ServerSocket.java:545)
            at java.net.ServerSocket.accept(ServerSocket.java:513)
            at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
            at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
            at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
            at java.lang.Thread.run(Thread.java:745)
    
    "RMI TCP Accept-1099" #11 daemon prio=5 os_prio=0 tid=0x14e50000 nid=0x4c7c runnable [0x156af000]
       java.lang.Thread.State: RUNNABLE
            at java.net.DualStackPlainSocketImpl.accept0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
            at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
            - locked <0x09eb9e90> (a java.net.SocksSocketImpl)
            at java.net.ServerSocket.implAccept(ServerSocket.java:545)
            at java.net.ServerSocket.accept(ServerSocket.java:513)
            at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
            at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
            at java.lang.Thread.run(Thread.java:745)
    
    "RMI TCP Accept-0" #10 daemon prio=5 os_prio=0 tid=0x15198400 nid=0x5d1c runnable [0x1561f000]
       java.lang.Thread.State: RUNNABLE
            at java.net.DualStackPlainSocketImpl.accept0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
            at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
            - locked <0x09eba190> (a java.net.SocksSocketImpl)
            at java.net.ServerSocket.implAccept(ServerSocket.java:545)
            at java.net.ServerSocket.accept(ServerSocket.java:513)
            at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
            at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
            at java.lang.Thread.run(Thread.java:745)
    
    "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x14c99c00 nid=0x26f0 runnable [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x14c91c00 nid=0x950 waiting on condition [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x14c91000 nid=0x53e4 waiting on condition [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x14cc6400 nid=0x3710 runnable [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x14c64800 nid=0x4a8c in Object.wait() [0x14eef000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x09eba9d8> (a java.lang.ref.ReferenceQueue$Lock)
            at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
            - locked <0x09eba9d8> (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=2 tid=0x14c63400 nid=0x5984 in Object.wait() [0x047ef000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x09ebab78> (a java.lang.ref.Reference$Lock)
            at java.lang.Object.wait(Object.java:502)
            at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
            - locked <0x09ebab78> (a java.lang.ref.Reference$Lock)
    
    "main" #1 prio=5 os_prio=0 tid=0x0028d400 nid=0x10c4 runnable [0x00d2f000]
       java.lang.Thread.State: RUNNABLE
            at java.net.DualStackPlainSocketImpl.accept0(Native Method)
            at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
            at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
            at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
            - locked <0x0a2e50d8> (a java.net.SocksSocketImpl)
            at java.net.ServerSocket.implAccept(ServerSocket.java:545)
            at java.net.ServerSocket.accept(ServerSocket.java:513)
            at org.apache.catalina.core.StandardServer.await(StandardServer.java:453)
            at org.apache.catalina.startup.Catalina.await(Catalina.java:777)
            at org.apache.catalina.startup.Catalina.start(Catalina.java:723)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:497)
            at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)
    
    "VM Thread" os_prio=2 tid=0x00eddc00 nid=0x3378 runnable
    
    "VM Periodic Task Thread" os_prio=2 tid=0x151ad800 nid=0x5988 waiting on condition
    
    JNI global references: 266
    View Code

    线程的状态

    在Java中线程的状态一共被分成6种:
      1、初始态(NEW)
        创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。
      2、运行态(RUNNABLE)
            在Java中,运行态包括 就绪态 和 运行态。
        ①就绪态
          该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行。
          所有就绪态的线程存放在就绪队列中。
        ②运行态
          获得CPU执行权,正在执行的线程。
          由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条运行态的线程。
      3、阻塞态(BLOCKED)
        当一条正在执行的线程请求某一资源失败时,就会进入阻塞态。
        而在Java中,阻塞态专指请求锁失败时进入的状态。
        由一个阻塞队列存放所有阻塞态的线程。
        处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。
      4、等待态(WAITING)
        当前线程中调用wait、join、park函数时,当前线程就会进入等待态。
        也有一个等待队列存放所有等待态的线程。
        线程处于等待态表示它需要等待其他线程的指示才能继续运行。
        进入等待态的线程会释放CPU执行权,并释放资源(如:锁)
      5、超时等待态(TIMED_WAITING)
        当运行中的线程调用sleep(time)、wait、join、parkNanos、parkUntil时,就会进入该状态;
        它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒;
        进入该状态后释放CPU执行权 和 占有的资源。
        与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。
      6、终止态(TERMINATED)
        线程执行结束后的状态。

    死锁问题

      如果在生产环境发生了死锁,我们将看到的是部署的程序没有任何反应了,这个时候我们可以借助jstack进行分析
    1、构造死锁
      编写代码,启动2个线程,Thread1拿到了obj1锁,准备去拿obj2锁时,obj2已经被Thread2锁定,所以发送了死锁。

    public class LockTest {
        //定义资源
        private static Object obj1=new Object();
        private static Object obj2=new Object();
        //线程A:先获取到资源1,然后休眠2s,再获取资源2
        private static class ThreadA implements Runnable{
            @Override
            public void run() {
                synchronized (obj1){
                    System.out.println("ThreadA获取到了OBJ1资源");
    
                    try {
                        //休眠2s,因为我们要将CPU资源让渡出去,这样线程B就可以先抢占obj2资源
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    synchronized (obj2){
                        System.out.println("ThreadA获取到了OBJ2资源");
                    }
                }
            }
        }
    
        private static class ThreadB implements Runnable{
            @Override
            public void run() {
                synchronized (obj2){
                    System.out.println("ThreadB获取到了OBJ2资源");
    
                    try {
                        //休眠2s,因为我们要将CPU资源让渡出去,这样线程B就可以先抢占obj2资源
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    synchronized (obj1){
                        System.out.println("ThreadA获取到了OBJ1资源");
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            new Thread(new ThreadA()).start();
            new Thread(new ThreadB()).start();
        }
    }
    使用jstack进行分析
     
     E:accpY2JVM>jstack>ps
    1595624
    16548 Main
    22292 RemoteMavenServer
    4452
    17656 Bootstrap
    2536 Jps
    10524 Launcher
    8828 TestDeadLock
    
    E:北大青鸟Y2JVM文件>jstack 8828
    2020-03-03 17:50:16
    Full thread dump Java HotSpot(TM) Client VM (25.73-b02 mixed mode):
    
    "DestroyJavaVM" #10 prio=5 os_prio=0 tid=0x031bc400 nid=0x2628 waiting on condition [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Thread-1" #9 prio=5 os_prio=0 tid=0x1588dc00 nid=0x35a4 waiting for monitor entry [0x15f0f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at TestDeadLock$Thread2.run(TestDeadLock.java:37)
            - waiting to lock <0x052e39d8> (a java.lang.Object)
            - locked <0x052e39e0> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    
    "Thread-0" #8 prio=5 os_prio=0 tid=0x1588d400 nid=0x2e40 waiting for monitor entry [0x15e7f000]
       java.lang.Thread.State: BLOCKED (on object monitor)
            at TestDeadLock$Thread1.run(TestDeadLock.java:20)
            - waiting to lock <0x052e39e0> (a java.lang.Object)
            - locked <0x052e39d8> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    
    "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x15825400 nid=0x4dec runnable [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x157d3800 nid=0x1df0 waiting on condition [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x157d0000 nid=0x2680 waiting on condition [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x157cf400 nid=0x2170 runnable [0x00000000]
       java.lang.Thread.State: RUNNABLE
    
    "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x157a6c00 nid=0x200c in Object.wait() [0x15abf000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x05206458> (a java.lang.ref.ReferenceQueue$Lock)
            at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
            - locked <0x05206458> (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=2 tid=0x0310e800 nid=0x17bc in Object.wait() [0x15a2f000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x05205f50> (a java.lang.ref.Reference$Lock)
            at java.lang.Object.wait(Object.java:502)
            at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
            - locked <0x05205f50> (a java.lang.ref.Reference$Lock)
    
    "VM Thread" os_prio=2 tid=0x0310bc00 nid=0x1c18 runnable
    
    "VM Periodic Task Thread" os_prio=2 tid=0x15887400 nid=0x2338 waiting on condition
    
    JNI global references: 6
    
    
    Found one Java-level deadlock:
    =============================
    "Thread-1":
      waiting to lock monitor 0x157a56a4 (object 0x052e39d8, a java.lang.Object),
      which is held by "Thread-0"
    "Thread-0":
      waiting to lock monitor 0x157a63c4 (object 0x052e39e0, a java.lang.Object),
      which is held by "Thread-1"
    
    Java stack information for the threads listed above:
    ===================================================
    "Thread-1":
            at TestDeadLock$Thread2.run(TestDeadLock.java:37)
            - waiting to lock <0x052e39d8> (a java.lang.Object)
            - locked <0x052e39e0> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    "Thread-0":
            at TestDeadLock$Thread1.run(TestDeadLock.java:20)
            - waiting to lock <0x052e39e0> (a java.lang.Object)
            - locked <0x052e39d8> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    
    Found 1 deadlock.

    在输出的信息中,已经看到了,发送一个死锁,关键看这个:

    "Thread-1":
            at TestDeadLock$Thread2.run(TestDeadLock.java:37)
            - waiting to lock <0x052e39d8> (a java.lang.Object)
            - locked <0x052e39e0> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)
    "Thread-0":
            at TestDeadLock$Thread1.run(TestDeadLock.java:20)
            - waiting to lock <0x052e39e0> (a java.lang.Object)
            - locked <0x052e39d8> (a java.lang.Object)
            at java.lang.Thread.run(Thread.java:745)

     可以清晰的看到:

        Thread2获取了<0x052e39e0>的锁,等待获取<0x052e39d8>这个锁

        Thread1获取了<0x052e39d8>的锁,等待获取<0x052e39e0>这个锁

        由此可见,发生了死锁;

  • 相关阅读:
    修改MFC标题栏上的图标
    【转】子窗口刷新父窗口的问题
    水晶报表添加引用
    【转】MetadataType的使用,MVC的Model层数据验证
    poj 1556 The Doors 线段相交判断+最短路
    poj 1269 Intersecting Lines 求直线交点 判断直线平行共线
    string 函数操作
    poj 1066 Treasure Hunt 线段相交判断
    poj 1410 Intersection 线段相交判断
    poj 3347 Kadj Squares 扩大数据化整数
  • 原文地址:https://www.cnblogs.com/dabrk/p/12410103.html
Copyright © 2020-2023  润新知