성능 최적화 -jstack의 사용

6, jstack을 사용

때때로 우리는 JVM 스레드의 구현을 볼 필요가, 예를 들어, 교착 상태가되었습니다, 서버의 CPU 부하가 갑자기 증가 발견 죽음의주기 등등, 우리는 어떻게 그것을 분석합니까?

프로그램이 실행되기 때문에, 거기에 우리가 내부 스레드 JVM의 구현을 볼 필요가 있도록 로그로부터 출력이 또한 문제를 참조하지 않는, 그리고 그 원인을 찾아 분석했다.

이 시간, 우리는 jstack을 명령의 도움이 필요 jstack을 역할은 스냅 샷을 실행하는 경우 JVM 스레드, 그것을 밖으로 인쇄하는 것입니다 :

#用法:jstack <pid>

[root@node01 bin]# jstack 2203
Full thread dump Java HotSpot(TM) 64‐Bit Server VM (25.141‐b15 mixed mode):

"Attach Listener" #24 daemon prio=9 os_prio=0 tid=0x00007fabb4001000 nid=0x906 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"http‐bio‐8080‐exec‐5" #23 daemon prio=5 os_prio=0 tid=0x00007fabb057c000 nid=0x8e1 waiting on condition [0x00007fabd05b8000]
java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)
‐ parking to wait for	<0x00000000f8508360> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awa it(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:44 2)
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:1 074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java
:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav a:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread
.java:61)
at java.lang.Thread.run(Thread.java:748)



"http‐bio‐8080‐exec‐4" #22 daemon prio=5 os_prio=0 tid=0x00007fab9c113800
nid=0x8e0 waiting on condition [0x00007fabd06b9000] java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
‐ parking to wait for	<0x00000000f8508360> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awa it(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:44 2)
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:1 074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java
:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav a:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread
.java:61)
at java.lang.Thread.run(Thread.java:748)

"http‐bio‐8080‐exec‐3" #21 daemon prio=5 os_prio=0 tid=0x0000000001aeb800 nid=0x8df waiting on condition [0x00007fabd09ba000]
java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)
‐ parking to wait for	<0x00000000f8508360> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awa it(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:44 2)
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:1 074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java
:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav a:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread
.java:61)
at java.lang.Thread.run(Thread.java:748)

"http‐bio‐8080‐exec‐2" #20 daemon prio=5 os_prio=0 tid=0x0000000001aea000 nid=0x8de waiting on condition [0x00007fabd0abb000]
java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)
‐ parking to wait for	<0x00000000f8508360> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awa it(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:44 2)
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:1 074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java
:1134)


at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav a:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread
.java:61)
at java.lang.Thread.run(Thread.java:748)

"http‐bio‐8080‐exec‐1" #19 daemon prio=5 os_prio=0 tid=0x0000000001ae8800 nid=0x8dd waiting on condition [0x00007fabd0bbc000]
java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)
‐ parking to wait for	<0x00000000f8508360> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awa it(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:44 2)
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:1 074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java
:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav a:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread
.java:61)
at java.lang.Thread.run(Thread.java:748)

"ajp‐bio‐8009‐AsyncTimeout" #17 daemon prio=5 os_prio=0 tid=0x00007fabe8128000 nid=0x8d0 waiting on condition [0x00007fabd0ece000]
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:748)

"ajp‐bio‐8009‐Acceptor‐0" #16 daemon prio=5 os_prio=0 tid=0x00007fabe82d4000 nid=0x8cf runnable [0x00007fabd0fcf000]
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
org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(Defaul tServerSocketFactory.java:60)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:220)
at java.lang.Thread.run(Thread.java:748)

"http‐bio‐8080‐AsyncTimeout" #15 daemon prio=5 os_prio=0 tid=0x00007fabe82d1800 nid=0x8ce waiting on condition [0x00007fabd10d0000]
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:748)

"http‐bio‐8080‐Acceptor‐0" #14 daemon prio=5 os_prio=0 tid=0x00007fabe82d0000 nid=0x8cd runnable [0x00007fabd11d1000]
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
org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(Defaul tServerSocketFactory.java:60)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:220)
at java.lang.Thread.run(Thread.java:748)

"ContainerBackgroundProcessor[StandardEngine[Catalina]]" #13 daemon prio=5 os_prio=0 tid=0x00007fabe82ce000 nid=0x8cc waiting on condition [0x00007fabd12d2000]
java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(C ontainerBase.java:1513)
at java.lang.Thread.run(Thread.java:748)

"GC Daemon" #10 daemon prio=2 os_prio=0 tid=0x00007fabe83b4000 nid=0x8b3 in Object.wait() [0x00007fabd1c2f000]
java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method)
‐waiting on <0x00000000e315c2d0> (a sun.misc.GC$LatencyLock) at sun.misc.GC$Daemon.run(GC.java:117)
‐locked <0x00000000e315c2d0> (a sun.misc.GC$LatencyLock)

"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007fabe80c3800 nid=0x8a5 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fabe80b6800 nid=0x8a4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fabe80b3800 nid=0x8a3 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fabe80b2000 nid=0x8a2 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE


"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fabe807f000 nid=0x8a1
in Object.wait() [0x00007fabd2a67000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method)
‐ waiting on <0x00000000e3162918> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
‐ locked <0x00000000e3162918> (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=0x00007fabe807a800 nid=0x8a0 in Object.wait() [0x00007fabd2b68000]
java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method)
‐waiting on <0x00000000e3162958> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
‐locked <0x00000000e3162958> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x00007fabe8009000 nid=0x89c runnable [0x00007fabed210000]
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
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(DelegatingMethodAccessorI mpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)


VM Thread" os_prio=0 tid=0x00007fabe8073000 nid=0x89f runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fabe801e000
nid=0x89d runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fabe8020000
nid=0x89e runnable

"VM Periodic Task Thread" os_prio=0 tid=0x00007fabe80d6800 nid=0x8a6
waiting on condition

JNI global references: 43

주 6.1, 스레드

그림 삽입 설명 여기
Java 스레드의 상태에서 여섯 종의 총으로 나누어집니다 :

  1. 초기 상태 (NEW)는
    당신이 스레드를 시작할 때 스레드 개체를 만들 수 있지만, 아직 시작을 호출하지 않은 (), 스레드는 초기 상태입니다. 상태 실행 준비 상태 및 실행 상태를 포함하여 자바의 실행 상태 (RUNNABLE).
  2. 준비 상태로
    이 상태에서 스레드만큼 CPU의 할당 실행이 실행할 수있는 수행하는 데 필요한 모든 자원에 액세스 할 수 있습니다. 스레드의 모든 준비 상태는 준비 큐에 저장.
  3. 상태 실행
    스레드를 실행하는, CPU를 수행 할 수있는 권한을 획득. 는 CPU가 한번에 하나의 스레드를 실행할 수 있기 때문에, 각 CPU 각각의 시간에 하나의 스레드 만 주행 상태.
  4. 차단 상태 (BLOCKED)
    스레드가 리소스 오류의 요구를 실행하는 경우, 차단 상태로 전환한다. 자바에서, 특히 경우 로크 요청 실패 상태가 된 상태를 차단 말한다. 모든 스레드의 큐를 저장하는 상태를 차단하는 차단. 요청이 성공하면, 그것은 실행을 기다리고, 준비 큐를 입력합니다, 요청 리소스에 계속 차단 상태에서 스레드.
  5. 대기 상태 (대기)
    현재 통화 대기 스레드, 가입, 공원 기능, 현재의 thread가 대기 상태가됩니다. 대기 큐가 대기 상태 모든 스레드를 보유하고도있다. 대기 상태의 스레드는 다른 스레드에 대한 지침을 계속 실행을 기다릴 필요가 말한다. 올바른 CPU의 구현을 출시 할 예정 대기 상태로 스레드, 그리고 (예 : 잠금) 해제 자원
  6. 제한 시간 대기 상태 (TIMED_WAITING)
    스레드 호출 수면 (시간)을 실행할 때, 대기, 가입 , parkNanos는, parkUntil가 상태를 입력 할 때,
    이 상태처럼, 이하 때문에 자원 요청을 기다려야하지만, 이니셔티브 입력 및 입력 한 후 다른 스레드를 깨워의 필요성,
    국가의 소유에 임원 전원과 CPU 자원의 릴리스. 그리고 대기 상태의 차이 : 차단이 자동으로 타임 아웃 후 큐에 입력 된 경쟁 잠금을 시작합니다.
  7. 종단 상태 (TERMINATED)
    종료 후의 스레드 실행 상태.

6.2 전투 : 교착 상태

교착 상태가 프로덕션 환경에서 발생하는 경우, 우리는 응답이의 배치를 볼 수 있습니다, 우리는 분석을위한 jstack을 사용할 수있다이 시간, 교착 상태의 실제 원인에의 모습을 보자.

6.2.1 건설 교착 상태

그들은 교착 상태를 보낼 수 있도록하는 코드를 작성이 Thread1이 잠금으로 obj1있어, 두 개의 스레드를 시작하기 위해 준비 obj2보다 Thread2 obj2보다 자물쇠가 잠겨 된 경우.

public class TestDeadLock {

    private static Object obj1 = new Object();
    private static Object obj2 = new Object();

    public static void main(String[] args) {
        new Thread(new Thread1()).start();
        new Thread(new Thread2()).start();
    }

    private static class Thread1 implements Runnable {
        @Override
        public void run() {
            synchronized (obj1) {
                System.out.println("Thread1 拿到了 obj1 的锁!");

                try {
                    // 停顿2秒的意义在于,让Thread2线程拿到obj2的锁
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (obj2) {
                    System.out.println("Thread1 拿到了 obj2 的锁!");
                }
            }
        }
    }


    private static class Thread2 implements Runnable {
        @Override
        public void run() {
            synchronized (obj2) {
                System.out.println("Thread2 拿到了 obj2 的锁!");

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj1) {
                    System.out.println("Thread2 拿到了 obj1 的锁!");
                }
            }
        }
    }
}

리눅스에서 6.2.2, 실행

그림 삽입 설명 여기

6.2.3 jstack을 사용하여 분석을

[root@node01 ~]# jstack 3256
Full thread dump Java HotSpot(TM) 64‐Bit Server VM (25.141‐b15 mixed mode):

"Attach Listener" #11 daemon prio=9 os_prio=0 tid=0x00007f5bfc001000 nid=0xcff waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #10 prio=5 os_prio=0 tid=0x00007f5c2c008800 nid=0xcb9 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Thread‐1" #9 prio=5 os_prio=0 tid=0x00007f5c2c0e9000 nid=0xcc5 waiting for monitor entry [0x00007f5c1c7f6000]
java.lang.Thread.State: BLOCKED (on object monitor) at TestDeadLock$Thread2.run(TestDeadLock.java:47)
‐waiting to lock <0x00000000f655dc40> (a java.lang.Object)
‐locked <0x00000000f655dc50> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748)

"Thread‐0" #8 prio=5 os_prio=0 tid=0x00007f5c2c0e7000 nid=0xcc4 waiting for monitor entry [0x00007f5c1c8f7000]
java.lang.Thread.State: BLOCKED (on object monitor) at TestDeadLock$Thread1.run(TestDeadLock.java:27)
‐waiting to lock <0x00000000f655dc50> (a java.lang.Object)
‐locked <0x00000000f655dc40> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748)

"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007f5c2c0d3000 nid=0xcc2 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f5c2c0b6000 nid=0xcc1 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f5c2c0b3000 nid=0xcc0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f5c2c0b1800 nid=0xcbf runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f5c2c07e800 nid=0xcbe in Object.wait() [0x00007f5c1cdfc000]
java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method)
‐ waiting on <0x00000000f6508ec8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
‐ locked <0x00000000f6508ec8> (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=0x00007f5c2c07a000 nid=0xcbd in Object.wait() [0x00007f5c1cefd000]
java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method)
‐waiting on <0x00000000f6506b68> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
‐locked <0x00000000f6506b68> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=0 tid=0x00007f5c2c072800 nid=0xcbc runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f5c2c01d800 nid=0xcba runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f5c2c01f800 nid=0xcbb runnable

"VM Periodic Task Thread" os_prio=0 tid=0x00007f5c2c0d6800 nid=0xcc3 waiting on condition

JNI global references: 6



Found one Java‐level deadlock:

=============================

"Thread‐1":
waiting to lock monitor 0x00007f5c080062c8 (object 0x00000000f655dc40, a java.lang.Object),
which is held by "Thread‐0" "Thread‐0":
waiting to lock monitor 0x00007f5c08004e28 (object 0x00000000f655dc50, 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:47)
‐waiting to lock <0x00000000f655dc40> (a java.lang.Object)
‐locked <0x00000000f655dc50> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748)
"Thread‐0":
at TestDeadLock$Thread1.run(TestDeadLock.java:27)
‐waiting to lock <0x00000000f655dc50> (a java.lang.Object)
‐locked <0x00000000f655dc40> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

정보 출력, 그것은 볼 수있다, 교착,이 열쇠를 발견 :

"Thread‐1":
at TestDeadLock$Thread2.run(TestDeadLock.java:47)
‐waiting to lock <0x00000000f655dc40> (a java.lang.Object)
‐locked <0x00000000f655dc50> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748)
"Thread‐0":
at TestDeadLock$Thread1.run(TestDeadLock.java:27)
‐waiting to lock <0x00000000f655dc50> (a java.lang.Object)
locked <0x00000000f655dc40> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748)

우리는 명확하게 볼 수 있습니다 :

  • Thread2 취득 <0x00000000f655dc50>의 취득을 대기하고, 잠금 장치를 <0x00000000f655dc40>잠금을
  • Thread1는 인수 <0x00000000f655dc40>의 취득을 대기하고, 잠금 장치를 <0x00000000f655dc50>잠금을

따라서, 교착 상태가 발생 하였다.

출시 1056 원저 · 원 찬양 888 ·은 30000 +를 볼

추천

출처blog.csdn.net/weixin_42528266/article/details/103986052