如下代码运行之后会产生死锁:t1线程持有对象锁a在等待对象锁b的释放,t2线程持有对象锁b在等待对象锁a释放
package com.leolee.multithreadProgramming.concurrent.syn;
import lombok.extern.slf4j.Slf4j;
/**
* @ClassName DeadLock
* @Description: 死锁问题
* @Author LeoLee
* @Date 2020/12/7
* @Version V1.0
**/
@Slf4j
public class DeadLock {
/*
* 功能描述: <br>
* 〈模拟死锁〉
* @Param: []
* @Return: void
* @Author: LeoLee
* @Date: 2020/12/7 12:24
*/
public static void testDeadLock() {
Object a = new Object();
Object b = new Object();
Thread t1 = new Thread(() -> {
synchronized (a) {
log.info("lock a");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
log.info("lock b");
log.info("do something");
}
}
}, "t1");
Thread t2 = new Thread(() -> {
synchronized (b) {
log.info("lock a");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a) {
log.info("lock b");
log.info("do something");
}
}
}, "t2");
t1.start();
t2.start();
}
public static void main(String[] args) {
DeadLock.testDeadLock();
}
}
定位死锁
jps + jstack 方法
通过 jps 命令查看java进程以及pid:
C:\leolee\development\workSpace\personal\java\multithread-programming>jps
10720 Launcher
12528 DeadLock
3748 Jps
6932
632 KotlinCompileDaemon
再通过 jstack 查看该java进程内的信息:
C:\leolee\development\workSpace\personal\java\multithread-programming>jstack 12528
2020-12-07 13:15:35
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.111-b14 mixed mode):
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x0000000002e43800 nid=0x1d44 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"t2" #13 prio=5 os_prio=0 tid=0x000000001f803000 nid=0x3588 waiting for monitor entry [0x000000002016f000]
java.lang.Thread.State: BLOCKED (on object monitor)//这里线程状态为阻塞,在某个对象锁的monitor上等待
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock.lambda$testDeadLock$1(DeadLock.java:55)
- waiting to lock <0x000000076bf7ca08> (a java.lang.Object)//等待对象锁<0x000000076bf7ca08>
- locked <0x000000076bf7ca18> (a java.lang.Object)//持有对象锁<0x000000076bf7ca18>
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock$$Lambda$2/1688376486.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
"t1" #12 prio=5 os_prio=0 tid=0x000000001f802800 nid=0x45fc waiting for monitor entry [0x000000002006f000]
java.lang.Thread.State: BLOCKED (on object monitor)//这里线程状态为阻塞,在某个对象锁的monitor上等待
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock.lambda$testDeadLock$0(DeadLock.java:40)
- waiting to lock <0x000000076bf7ca18> (a java.lang.Object)//等待对象锁<0x000000076bf7ca18>
- locked <0x000000076bf7ca08> (a java.lang.Object)//持有对象锁<0x000000076bf7ca08>
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock$$Lambda$1/1942406066.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001eb20800 nid=0x2f70 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001ea87800 nid=0x39f8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001ea7b000 nid=0x738 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001ea76000 nid=0x2a34 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x000000001ea73000 nid=0x213c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001ea4b800 nid=0x17d0 runnable [0x000000001f0be000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x000000076b9cbdc8> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x000000076b9cbdc8> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000001e932000 nid=0x3f20 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001e931800 nid=0x3748 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001e8c0800 nid=0x20d0 in Object.wait() [0x000000001ed9f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b708e98> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
- locked <0x000000076b708e98> (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=0x0000000002f39800 nid=0x3670 in Object.wait() [0x000000001e89f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076b706b40> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076b706b40> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=2 tid=0x000000001c9ba000 nid=0x3f60 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002e59800 nid=0x44b0 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002e5b000 nid=0x1fa0 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002e5c800 nid=0x9b8 runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002e5e000 nid=0x24b0 runnable
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002e61800 nid=0x2d3c runnable
"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002e62800 nid=0x8e0 runnable
"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002e65800 nid=0x28b8 runnable
"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002e67000 nid=0x4b9c runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001ebd8000 nid=0x1b24 waiting on condition
JNI global references: 332
Found one Java-level deadlock://找到一处死锁
=============================
"t2":
waiting to lock monitor 0x000000001c9c3258 (object 0x000000076bf7ca08, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x000000001c9c0f48 (object 0x000000076bf7ca18, a java.lang.Object),
which is held by "t2"
Java stack information for the threads listed above://死锁详细信息
===================================================
"t2":
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock.lambda$testDeadLock$1(DeadLock.java:55)
- waiting to lock <0x000000076bf7ca08> (a java.lang.Object)
- locked <0x000000076bf7ca18> (a java.lang.Object)
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock$$Lambda$2/1688376486.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
"t1":
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock.lambda$testDeadLock$0(DeadLock.java:40)
- waiting to lock <0x000000076bf7ca18> (a java.lang.Object)
- locked <0x000000076bf7ca08> (a java.lang.Object)
at com.leolee.multithreadProgramming.concurrent.syn.DeadLock$$Lambda$1/1942406066.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
jconsole 方法
jdk中自带的命令行工具,在jdk目录的bin文件夹下
也可以在windows搜索中搜索jconsole
选择java进程:
成功连接该进程
查看线程情况: