public class DeadlockProgram { public static void main(String[] args) throws Exception { Object resourceA = new Object(); Object resourceB = new Object(); Thread threadLockingResourceAFirst = new Thread(new DeadlockRunnable(resourceA, resourceB)); Thread threadLockingResourceBFirst = new Thread(new DeadlockRunnable(resourceB, resourceA)); threadLockingResourceAFirst.start(); Thread.sleep(500); threadLockingResourceBFirst.start(); } private static class DeadlockRunnable implements Runnable { private final Object firstResource; private final Object secondResource; public DeadlockRunnable(Object firstResource, Object secondResource) { this.firstResource = firstResource; this.secondResource = secondResource; } @Override public void run() { try { synchronized(firstResource) { printLockedResource(firstResource); Thread.sleep(1000); synchronized(secondResource) { printLockedResource(secondResource); } } } catch (InterruptedException e) { System.out.println("Exception occurred: " + e); } } private static void printLockedResource(Object resource) { System.out.println(Thread.currentThread().getName() + ": locked resource -> " + resource); } } }
Thread-0: locked resource -> java.lang.Object@149bc794 Thread-1: locked resource -> java.lang.Object@17c10009
$ jps 11568 DeadlockProgram 15584 Jps 15636
jstack -l 11568 > thread_dump.txt
kill -3 11568
2018-06-19 16:44:44 Full thread dump Java HotSpot (TM) 64-Bit Server VM (10.0.1 + 10 mixed mode): Threads class SMR info: _java_thread_list = 0x00000250e5488a00, length = 13, elements = { 0x00000250e4979000, 0x00000250e4982800, 0x00000250e52f2800, 0x00000250e4992800, 0x00000250e4995800, 0x00000250e49a5800, 0x00000250e49ae800, 0x00000250e5324000, 0x00000250e54cd800, 0x00000250e54cf000, 0x00000250e54d1800, 0x00000250e54d2000, 0x00000250e54d0800 } "Reference Handler" # 2 daemon prio = 10 os_prio = 2 tid = 0x00000250e4979000 nid = 0x3c28 waiting on condition [0x000000b82a9ff000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList (java.base@10.0.1/Native Method) at java.lang.ref.Reference.processPendingReferences (java.base@10.0.1/Reference.java: 174) at java.lang.ref.Reference.access $ 000 (java.base@10.0.1/Reference.java: 44) at java.lang.ref.Reference $ ReferenceHandler.run (java.base@10.0.1/Reference.java: 138) Locked ownable synchronizers: - None "Finalizer" # 3 daemon prio = 8 os_prio = 1 tid = 0x00000250e4982800 nid = 0x2a54 in Object.wait () [0x000000b82aaff000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait (java.base@10.0.1/Native Method) - waiting on <0x0000000089509410> (a java.lang.ref.ReferenceQueue $ Lock) at java.lang.ref.ReferenceQueue.remove (java.base@10.0.1/ReferenceQueue.java: 151) - waiting for re-lock in wait () <0x0000000089509410> (a java.lang.ref.ReferenceQueue $ Lock) at java.lang.ref.ReferenceQueue.remove (java.base@10.0.1/ReferenceQueue.java: 172) at java.lang.ref.Finalizer $ FinalizerThread.run (java.base@10.0.1/Finalizer.java: 216) Locked ownable synchronizers: - None "Signal Dispatcher" # 4 daemon prio = 9 os_prio = 2 tid = 0x00000250e52f2800 nid = 0x2184 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Attach Listener" # 5 daemon prio = 5 os_prio = 2 tid = 0x00000250e4992800 nid = 0x1624 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread0" # 6 daemon prio = 9 os_prio = 2 tid = 0x00000250e4995800 nid = 0x4198 waiting on condition [0x000000000000000000] java.lang.Thread.State: RUNNABLE No compile task Locked ownable synchronizers: - None "C2 CompilerThread1" # 7 daemon prio = 9 os_prio = 2 tid = 0x00000250e49a5800 nid = 0x3b98 waiting on condition [0x000000000000000000] java.lang.Thread.State: RUNNABLE No compile task Locked ownable synchronizers: - None "C1 CompilerThread2" # 8 daemon prio = 9 os_prio = 2 tid = 0x00000250e49ae800 nid = 0x1a84 waiting on condition [0x000000000000000000] java.lang.Thread.State: RUNNABLE No compile task Locked ownable synchronizers: - None "Sweeper thread" # 9 daemon prio = 9 os_prio = 2 tid = 0x00000250e5324000 nid = 0x5f0 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Service Thread" # 10 daemon prio = 9 os_prio = 0 tid = 0x00000250e54cd800 nid = 0x169c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None Common cleaner # 11 daemon prio = 8 os_prio = 1 tid = 0x00000250e54cf000 nid = 0x1610 in Object.wait () [0x000000b82b2fe000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait (java.base@10.0.1/Native Method) - waiting on <0x000000008943e600> (a java.lang.ref.ReferenceQueue $ Lock) at java.lang.ref.ReferenceQueue.remove (java.base@10.0.1/ReferenceQueue.java: 151) - waiting for re-lock in wait () <0x000000008943e600> (a java.lang.ref.ReferenceQueue $ Lock) at jdk.internal.ref.CleanerImpl.run (java.base@10.0.1/CleanerImpl.java: 148) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) at jdk.internal.misc.InnocuousThread.run (java.base@10.0.1/InnocuousThread.java: 134) Locked ownable synchronizers: - None "Thread-0" # 12 prio = 5 os_prio = 0 tid = 0x00000250e54d1800 nid = 0xdec waiting for monitor entry [0x000000b82b4ff000] java.lang.Thread.State: BLOCKED (on object monitor) at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465b0> (a java.lang.Object) - locked <0x00000000894465a0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) Locked ownable synchronizers: - None "Thread-1" # 13 prio = 5 os_prio = 0 tid = 0x00000250e54d2000 nid = 0x415c waiting for monitor entry [0x000000b82b5ff000] java.lang.Thread.State: BLOCKED (on object monitor) at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465a0> (a java.lang.Object) - locked <0x00000000894465b0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) Locked ownable synchronizers: - None "DestroyJavaVM" # 14 prio = 5 os_prio = 0 tid = 0x00000250e54d0800 nid = 0x2b8c waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "VM Thread" os_prio = 2 tid = 0x00000250e496d800 nid = 0x1920 runnable "GC Thread # 0" os_prio = 2 tid = 0x00000250c35b5800 nid = 0x310c runnable "GC Thread # 1" os_prio = 2 tid = 0x00000250c35b8000 nid = 0x12b4 runnable "GC Thread # 2" os_prio = 2 tid = 0x00000250c35ba800 nid = 0x43f8 runnable "GC Thread # 3" os_prio = 2 tid = 0x00000250c35c0800 nid = 0x20c0 runnable "G1 Main Marker" os_prio = 2 tid = 0x00000250c3633000 nid = 0x4068 runnable "G1 Conc # 0" os_prio = 2 tid = 0x00000250c3636000 nid = 0x3e28 runnable "G1 Refine # 0" os_prio = 2 tid = 0x00000250c367e000 nid = 0x3c0c runnable "G1 Refine # 1" os_prio = 2 tid = 0x00000250e47fb800 nid = 0x3890 runnable "G1 Refine # 2" os_prio = 2 tid = 0x00000250e47fc000 nid = 0x32a8 runnable "G1 Refine # 3" os_prio = 2 tid = 0x00000250e47fd800 nid = 0x3d00 runnable "G1 Young RemSet Sampling" os_prio = 2 tid = 0x00000250e4800800 nid = 0xef4 runnable "VM Periodic Task Thread" os_prio = 2 tid = 0x00000250e54d6800 nid = 0x3468 waiting on condition JNI global references: 2 Found one java-level deadlock: ============================= "Thread-0": monitor 0x00000250e4982480 (object 0x00000000894465b0, a java.lang.Object) waiting for lock which is held by "Thread-1" "Thread-1": monitor 0x00000250e4982380 (object 0x00000000894465a0, a java.lang.Object), which is held by "Thread-0" Java stack information listed above: ================================================= = "Thread-0": at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465b0> (a java.lang.Object) - locked <0x00000000894465a0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) "Thread-1": at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465a0> (a java.lang.Object) - locked <0x00000000894465b0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) Found 1 deadlock.
2018-06-19 16:44:44 Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.1+10 mixed mode):
Threads class SMR info: _java_thread_list = 0x00000250e5488a00, length = 13, elements = { 0x00000250e4979000, 0x00000250e4982800, 0x00000250e52f2800, 0x00000250e4992800, 0x00000250e4995800, 0x00000250e49a5800, 0x00000250e49ae800, 0x00000250e5324000, 0x00000250e54cd800, 0x00000250e54cf000, 0x00000250e54d1800, 0x00000250e54d2000, 0x00000250e54d0800 }
"Reference Handler" # 2 ... tid = 0x00000250e4979000 ... "Finalizer" # 3 ... tid = 0x00000250e4982800 ... "Signal Dispatcher" # 4 ... tid = 0x00000250e52f2800 ... "Attach Listener" # 5 ... tid = 0x00000250e4992800 ... "C2 CompilerThread0" # 6 ... tid = 0x00000250e4995800 ... "C2 CompilerThread1" # 7 ... tid = 0x00000250e49a5800 ... "C1 CompilerThread2" # 8 ... tid = 0x00000250e49ae800 ... "Sweeper thread" # 9 ... tid = 0x00000250e5324000 ... "Service Thread" # 10 ... tid = 0x00000250e54cd800 ... Common Cleaner # 11 ... tid = 0x00000250e54cf000 ... "Thread-0" # 12 ... tid = 0x00000250e54d1800 ... "Thread-1" # 13 ... tid = 0x00000250e54d2000 ... "DestroyJavaVM" # 14 ... tid = 0x00000250e54d0800 ...
"Reference Handler" # 2 daemon prio = 10 os_prio = 2 tid = 0x00000250e4979000 nid = 0x3c28 waiting on condition [0x000000b82a9ff000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList (java.base@10.0.1/Native Method) at java.lang.ref.Reference.processPendingReferences (java.base@10.0.1/Reference.java: 174) at java.lang.ref.Reference.access $ 000 (java.base@10.0.1/Reference.java: 44) at java.lang.ref.Reference $ ReferenceHandler.run (java.base@10.0.1/Reference.java: 138) Locked ownable synchronizers: - None
Section | Example | Description |
---|---|---|
Name | "Reference Handler" | The human-readable name of the thread. The name can be set by calling the Thread object's setName method. And get through a call to getName |
ID | # 2 | Unique ID assigned to each object of class Thread . An ID is generated for threads in the system. The initial value is 1. Each newly created thread is assigned its own ID, previously increased by 1. This property of the “read-only” stream can be obtained using the getId function of the object of the class Thread . |
Daemon status | daemon | The flag is a sign that the thread is a daemon. If it is a demon, then the flag will be set. For example, Thread-0 is not a daemon. |
Priority | prio = 10 | The numeric priority of the java stream. Note that this priority does not necessarily correspond to the priority of the associated thread in the operating system. To set the priority you can use the setPriority method of an object of class Thread , and to get method getPriority . |
OS Thread Priority | os_prio = 2 | The priority of the thread in the operating system. This priority may differ from the one assigned to the coherent java stream. |
Address | tid = 0x00000250e4979000 | Java stream address This address is a pointer to a Java Native Interface (JNI) native object of class Thread (a C ++ Thread object that is associated with a Java stream via JNI). This value is obtained by casting a pointer to this. (a C ++ object that is associated with this Java stream) to integer. Cm. line 879 in hotspot / share / runtime / thread.cpp : st-> print ("tid =" INTPTR_FORMAT "", p2i (this)); Although the key for this object ( tid ) may be similar to a stream ID, in fact, this is the address of the connected JNI C ++ Thread object, and this is not the value that returns the getId method of the Java Thread object. |
OS Thread ID | nid = 0x3c28 | The unique identifier for the operating system thread to which the Java thread is bound. This value is output by the following code: line 42 in hotspot / share / runtime / osThread.cpp : st-> print ("nid = 0x% x", thread_id ()); |
Status | waiting on condition | The human-readable status of the current thread. This line prints additional information to the simple status of the stream (see below), which can be used to understand what the thread was going to do (i.e., did the thread try to get the lock or waited for the unlock condition to be met). |
Last Known Java Stack Pointer | [0x000000b82a9ff000] | The last known pointer to the stack (SP) associated with this thread. This value is obtained using native C ++ code mixed with Java code using JNI. The value returned by the function last_Java_sp () , line 2886 in hotspot / share / runtime / thread.cpp : st-> print_cr ("[" INTPTR_FORMAT "]", (intptr_t) last_Java_sp () & ~ right_n_bits (12)); For simple thread dumps, this information is almost useless. However, in difficult cases, SP can be used to track locks. |
"Thread-0" # 12 prio = 5 os_prio = 0 tid = 0x00000250e54d1800 nid = 0xdec waiting for monitor entry [0x000000b82b4ff000] java.lang.Thread.State: BLOCKED (on object monitor) at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465b0> (a java.lang.Object) - locked <0x00000000894465a0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) Locked ownable synchronizers: - None
"VM Thread" os_prio = 2 tid = 0x00000250e496d800 nid = 0x1920 runnable "GC Thread # 0" os_prio = 2 tid = 0x00000250c35b5800 nid = 0x310c runnable "GC Thread # 1" os_prio = 2 tid = 0x00000250c35b8000 nid = 0x12b4 runnable "GC Thread # 2" os_prio = 2 tid = 0x00000250c35ba800 nid = 0x43f8 runnable "GC Thread # 3" os_prio = 2 tid = 0x00000250c35c0800 nid = 0x20c0 runnable "G1 Main Marker" os_prio = 2 tid = 0x00000250c3633000 nid = 0x4068 runnable "G1 Conc # 0" os_prio = 2 tid = 0x00000250c3636000 nid = 0x3e28 runnable "G1 Refine # 0" os_prio = 2 tid = 0x00000250c367e000 nid = 0x3c0c runnable "G1 Refine # 1" os_prio = 2 tid = 0x00000250e47fb800 nid = 0x3890 runnable "G1 Refine # 2" os_prio = 2 tid = 0x00000250e47fc000 nid = 0x32a8 runnable "G1 Refine # 3" os_prio = 2 tid = 0x00000250e47fd800 nid = 0x3d00 runnable "G1 Young RemSet Sampling" os_prio = 2 tid = 0x00000250e4800800 nid = 0xef4 runnable "VM Periodic Task Thread" os_prio = 2 tid = 0x00000250e54d6800 nid = 0x3468 waiting on condition
JNI global references: 2
Found one java-level deadlock: ============================= "Thread-0": monitor 0x00000250e4982480 (object 0x00000000894465b0, a java.lang.Object) waiting for lock which is held by "Thread-1" "Thread-1": monitor 0x00000250e4982380 (object 0x00000000894465a0, a java.lang.Object), which is held by "Thread-0" Java stack information listed above: ================================================= = "Thread-0": at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465b0> (a java.lang.Object) - locked <0x00000000894465a0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) "Thread-1": at DeadlockProgram $ DeadlockRunnable.run (DeadlockProgram.java:34) - waiting to lock <0x00000000894465a0> (a java.lang.Object) - locked <0x00000000894465b0> (a java.lang.Object) at java.lang.Thread.run (java.base@10.0.1/Thread.java: 844) Found 1 deadlock.
printLockedResource (secondResource);
public class DeadlockProgram { public static void main(String[] args) throws Exception { Object resourceA = new Object(); Object resourceB = new Object(); Thread threadLockingResourceAFirst = new Thread(new DeadlockRunnable(resourceA, resourceB)); Thread threadLockingResourceBFirst = new Thread(new DeadlockRunnable(resourceA, resourceB)); threadLockingResourceAFirst.start(); Thread.sleep(500); threadLockingResourceBFirst.start(); } private static class DeadlockRunnable implements Runnable { private final Object firstResource; private final Object secondResource; public DeadlockRunnable(Object firstResource, Object secondResource) { this.firstResource = firstResource; this.secondResource = secondResource; } @Override public void run() { try { synchronized (firstResource) { printLockedResource(firstResource); Thread.sleep(1000); synchronized (secondResource) { printLockedResource(secondResource); } } } catch (InterruptedException e) { System.out.println("Exception occurred: " + e); } } private static void printLockedResource(Object resource) { System.out.println(Thread.currentThread().getName() + ": locked resource -> " + resource); } } }
Thread-0: locked resource -> java.lang.Object@1ad895d1 Thread-0: locked resource -> java.lang.Object@6e41d7dd Thread-1: locked resource -> java.lang.Object@1ad895d1 Thread-1: locked resource -> java.lang.Object@6e41d7dd
Source: https://habr.com/ru/post/427513/
All Articles