一、概述
两个或两个以上的进程在执行任务的过程中,因争抢资源而造成的一种互相等待的现象,若无外力干涉将无法推进下去。
二、死锁演示
public class HoldLockThread implements Runnable {
private String lock1;
private String lock2;
public HoldLockThread(String lock1, String lock2) {
this.lock1 = lock1;
this.lock2 = lock2;
}
// A线程进来获得锁A,(等2s)然后B线程进来获得锁B,然后A想去获得锁B(此时B还持有锁B)
@Override
public void run() {
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + "\t自己持有lock1:" + lock1 + ",尝试获得lock2:" + lock2);
try {
// 等待两秒,让第二B线程启动并获取锁B
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + "\t自己持有lock2:" + lock2 + ",尝试获得lock1:" + lock1);
}
}
}
}
public class DeadLockDemo {
public static void main(String[] args) {
String lockA = "lockA";
String lockB = "lockB";
new Thread(new HoldLockThread(lockA,lockB),"ThreadAAA").start();
new Thread(new HoldLockThread(lockB,lockA),"ThreadBBB").start();
}
}
1、上述代码就会出现死锁,A线程进来获得锁A,(等2s)然后B线程进来获得锁B,然后A想去获得锁B(此时B还持有锁B)。
2、首先通过jps命令定位进程号,可以看到DeadLockDemo正在运行,进程号是54760
superking@wangchaodeMacBook-Pro examination % jps -l
54835 jdk.jcmd/sun.tools.jps.Jps
54708 org.jetbrains.idea.maven.server.RemoteMavenServer36
54758 org.jetbrains.jps.cmdline.Launcher
54760 com.supkingx.base.f_thread.deadlock.DeadLockDemo
3、通过jstack分析问题。
superking@wangchaodeMacBook-Pro examination % jstack 54760
2021-10-17 10:45:26
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.251-b08 mixed mode):
"Attach Listener" #14 daemon prio=9 os_prio=31 tid=0x00007fb823810000 nid=0xa703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" #13 prio=5 os_prio=31 tid=0x00007fb824080000 nid=0xe03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"ThreadBBB" #12 prio=5 os_prio=31 tid=0x00007fb82980a000 nid=0xa803 waiting for monitor entry [0x0000700004e87000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
- waiting to lock <0x000000076ac231d0> (a java.lang.String)
- locked <0x000000076ac23208> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"ThreadAAA" #11 prio=5 os_prio=31 tid=0x00007fb82407f000 nid=0x5a03 waiting for monitor entry [0x0000700004d84000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
- waiting to lock <0x000000076ac23208> (a java.lang.String)
- locked <0x000000076ac231d0> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #10 daemon prio=9 os_prio=31 tid=0x00007fb825819800 nid=0xa903 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #9 daemon prio=9 os_prio=31 tid=0x00007fb82402e800 nid=0x5503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007fb82402d800 nid=0x3d03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007fb82505b800 nid=0x3e03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007fb82505b000 nid=0x4003 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007fb82606c800 nid=0x3a03 runnable [0x000070000466f000]
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 <0x000000076ac83cc0> (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 <0x000000076ac83cc0> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:47)
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fb82500d000 nid=0x3903 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fb82402d000 nid=0x4d03 in Object.wait() [0x0000700004363000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ab08ee0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x000000076ab08ee0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fb825811000 nid=0x3403 in Object.wait() [0x0000700004260000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ab06c00> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076ab06c00> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=31 tid=0x00007fb826812800 nid=0x3303 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fb824013000 nid=0x2207 runnable
"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fb825008800 nid=0x2103 runnable
"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fb825009000 nid=0x1f03 runnable
"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fb825808800 nid=0x2a03 runnable
"GC task thread#4 (ParallelGC)" os_prio=31 tid=0x00007fb825809000 nid=0x2c03 runnable
"GC task thread#5 (ParallelGC)" os_prio=31 tid=0x00007fb825809800 nid=0x5403 runnable
"GC task thread#6 (ParallelGC)" os_prio=31 tid=0x00007fb82500a000 nid=0x2f03 runnable
"GC task thread#7 (ParallelGC)" os_prio=31 tid=0x00007fb82500a800 nid=0x3003 runnable
"GC task thread#8 (ParallelGC)" os_prio=31 tid=0x00007fb82580a000 nid=0x3103 runnable
"GC task thread#9 (ParallelGC)" os_prio=31 tid=0x00007fb824014000 nid=0x5003 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007fb82a008800 nid=0x5803 waiting on condition
JNI global references: 15
Found one Java-level deadlock:
=============================
"ThreadBBB":
waiting to lock monitor 0x00007fb82602b5e8 (object 0x000000076ac231d0, a java.lang.String),
which is held by "ThreadAAA"
"ThreadAAA":
waiting to lock monitor 0x00007fb8260290c8 (object 0x000000076ac23208, a java.lang.String),
which is held by "ThreadBBB"
Java stack information for the threads listed above:
===================================================
"ThreadBBB":
at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
- waiting to lock <0x000000076ac231d0> (a java.lang.String)
- locked <0x000000076ac23208> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"ThreadAAA":
at com.supkingx.base.f_thread.deadlock.HoldLockThread.run(HoldLockThread.java:32)
- waiting to lock <0x000000076ac23208> (a java.lang.String)
- locked <0x000000076ac231d0> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
通过上述输出结果可以看到最后一行 Found 1 deadlock.。
根据输出结果如下,出现了互相等待,即产生了死锁