死锁是什么
死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。
产生死锁的原因
- 系统资源不足
- 进程运行推进的顺序不合适
- 资源分配不当
死锁代码示例
public class DeadLockDemo {
static Object a=new Object();
static Object b=new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (a){
System.out.println("t1线程持有a锁,试图获取b锁");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b){
System.out.println("t1线程获取到b锁");
}
}
},"t1").start();
new Thread(() -> {
synchronized (b){
System.out.println("t2线程持有a锁,试图获取a锁");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a){
System.out.println("t2线程获取到a锁");
}
}
},"t2").start();
}
}
如何排查死锁
命令行
jsp -l
jstack pid
leam@Leam-MacBook-Pro locks % jps -l
3266 com.intellij.idea.Main
1609 /Users/xxx/.vscode/extensions/redhat.java-1.26.0-darwin-arm64/server/plugins/org.eclipse.equinox.launcher_1.6.700.v20231214-2017.jar
6301 org.jetbrains.jps.cmdline.Launcher
6302 dev.matrixlab.juc.locks.DeadLockDemo
6318 jdk.jcmd/sun.tools.jps.Jps
leam@Leam-MacBook-Pro locks % jstack 6302
2024-01-24 23:20:20
Full thread dump OpenJDK 64-Bit Server VM (25.382-b05 mixed mode):
"Attach Listener" #14 daemon prio=9 os_prio=31 tid=0x0000000150026000 nid=0x4707 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" #13 prio=5 os_prio=31 tid=0x000000014e034000 nid=0x1103 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"t2" #12 prio=5 os_prio=31 tid=0x000000014d020000 nid=0x5b03 waiting for monitor entry [0x000000017861e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at dev.matrixlab.juc.locks.DeadLockDemo.lambda$main$1(DeadLockDemo.java:33)
- waiting to lock <0x0000000715778fa0> (a java.lang.Object)
- locked <0x0000000715778fb0> (a java.lang.Object)
at dev.matrixlab.juc.locks.DeadLockDemo$$Lambda$2/396873410.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
"t1" #11 prio=5 os_prio=31 tid=0x000000014d01d000 nid=0x5a03 waiting for monitor entry [0x0000000178412000]
java.lang.Thread.State: BLOCKED (on object monitor)
at dev.matrixlab.juc.locks.DeadLockDemo.lambda$main$0(DeadLockDemo.java:19)
- waiting to lock <0x0000000715778fb0> (a java.lang.Object)
- locked <0x0000000715778fa0> (a java.lang.Object)
at dev.matrixlab.juc.locks.DeadLockDemo$$Lambda$1/1721931908.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
"Service Thread" #10 daemon prio=9 os_prio=31 tid=0x000000013d02c000 nid=0x5803 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #9 daemon prio=9 os_prio=31 tid=0x000000014d81b000 nid=0x7f03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x000000014d81a800 nid=0x5503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x000000014e022000 nid=0x4f03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x000000014e021000 nid=0x4e03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x000000014f8f2800 nid=0x5203 runnable [0x000000016f47e000]
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:171)
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 <0x0000000715871138> (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 <0x0000000715871138> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:53)
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x000000014f864800 nid=0x4b03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x000000015000a800 nid=0x3403 in Object.wait() [0x000000016ef4e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000715588f08> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x0000000715588f08> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:188)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x000000014f850000 nid=0x3503 in Object.wait() [0x000000016ed42000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000715586ba0> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000715586ba0> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=31 tid=0x000000014f84b000 nid=0x3203 runnable
"ParGC Thread#0" os_prio=31 tid=0x000000014d80a800 nid=0x2203 runnable
"ParGC Thread#1" os_prio=31 tid=0x000000014d816800 nid=0x3f03 runnable
"ParGC Thread#2" os_prio=31 tid=0x000000014d817800 nid=0x3d03 runnable
"ParGC Thread#3" os_prio=31 tid=0x000000013d00f000 nid=0x3b03 runnable
"ParGC Thread#4" os_prio=31 tid=0x000000013d00f800 nid=0x2b03 runnable
"ParGC Thread#5" os_prio=31 tid=0x000000014d818000 nid=0x2d03 runnable
"ParGC Thread#6" os_prio=31 tid=0x000000014d819000 nid=0x3803 runnable
"ParGC Thread#7" os_prio=31 tid=0x000000014d819800 nid=0x2f03 runnable
"ParGC Thread#8" os_prio=31 tid=0x000000014e009800 nid=0x3003 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x000000014f8f3800 nid=0x7e03 waiting on condition
JNI global references: 320
Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x000000012d00d8b0 (object 0x0000000715778fa0, a java.lang.Object),
which is held by "t1"
"t1":
waiting to lock monitor 0x000000012d00b020 (object 0x0000000715778fb0, a java.lang.Object),
which is held by "t2"
Java stack information for the threads listed above:
===================================================
"t2":
at dev.matrixlab.juc.locks.DeadLockDemo.lambda$main$1(DeadLockDemo.java:33)
- waiting to lock <0x0000000715778fa0> (a java.lang.Object)
- locked <0x0000000715778fb0> (a java.lang.Object)
at dev.matrixlab.juc.locks.DeadLockDemo$$Lambda$2/396873410.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
"t1":
at dev.matrixlab.juc.locks.DeadLockDemo.lambda$main$0(DeadLockDemo.java:19)
- waiting to lock <0x0000000715778fb0> (a java.lang.Object)
- locked <0x0000000715778fa0> (a java.lang.Object)
at dev.matrixlab.juc.locks.DeadLockDemo$$Lambda$1/1721931908.run(Unknown Source)
at java.lang.Thread.run(Thread.java:750)
Found 1 deadlock.
图形化界面
jconsole