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