java死锁产生的条件:
A线程持有锁A的同时,尝试获取锁B。
B线程持有锁B的同时,尝试获取锁A。
测试代码:
package com.zhangye;
import java.util.concurrent.TimeUnit;
class HoldLockThread implements Runnable{
private String lockA;
private String lockB;
public HoldLockThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA) {
System.out.println(Thread.currentThread().getName()+"\t 自己持有lockA,尝试获得lockB");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB) {
System.out.println(Thread.currentThread().getName()+"\t 自己有持有lockB,尝试获得lockA");
}
}
}
}
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.用jdk自带的jps命令查看进程ID
2.用jdk自带的jstack命令加上进程ID,查看具体是哪里产生死锁
排查的结果:`
2021-01-17 22:00:23
Full thread dump Java HotSpot™ Client VM (25.151-b12 mixed mode):
“DestroyJavaVM” #11 prio=5 os_prio=0 tid=0x02d1cc00 nid=0x1764 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
“ThreadBBB” #10 prio=5 os_prio=0 tid=0x1550a000 nid=0x1324 waiting for monitor entry [0x15bcf000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.zhangye.HoldLockThread.run(DeadLockDemo.java:26)
- waiting to lock <0x051a67f0> (a java.lang.String)
- locked <0x051a6818> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
“ThreadAAA” #9 prio=5 os_prio=0 tid=0x15599400 nid=0x5c waiting for monitor entry [0x15b3f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.zhangye.HoldLockThread.run(DeadLockDemo.java:26)
- waiting to lock <0x051a6818> (a java.lang.String)
- locked <0x051a67f0> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
“Service Thread” #8 daemon prio=9 os_prio=0 tid=0x15505800 nid=0x1e7c runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
“C1 CompilerThread0” #7 daemon prio=9 os_prio=2 tid=0x154fa800 nid=0x1758 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
“Monitor Ctrl-Break” #6 daemon prio=5 os_prio=0 tid=0x154f9800 nid=0x8b0 runnable [0x158ff000]
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 <0x051f06c8> (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 <0x051f06c8> (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=0x154c0c00 nid=0x3bcc waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
“Signal Dispatcher” #4 daemon prio=9 os_prio=2 tid=0x15496c00 nid=0x3bf8 runnable [0x00000000]
java.lang.Thread.State: RUNNABLE
“Finalizer” #3 daemon prio=8 os_prio=1 tid=0x1547a000 nid=0x2518 in Object.wait() [0x156ef000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x05007ee0> (a java.lang.ref.ReferenceQueue
L
o
c
k
)
a
t
j
a
v
a
.
l
a
n
g
.
r
e
f
.
R
e
f
e
r
e
n
c
e
Q
u
e
u
e
.
r
e
m
o
v
e
(
R
e
f
e
r
e
n
c
e
Q
u
e
u
e
.
j
a
v
a
:
143
)
−
l
o
c
k
e
d
<
0
x
05007
e
e
0
>
(
a
j
a
v
a
.
l
a
n
g
.
r
e
f
.
R
e
f
e
r
e
n
c
e
Q
u
e
u
e
Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x05007ee0> (a java.lang.ref.ReferenceQueue
Lock)atjava.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)−locked<0x05007ee0>(ajava.lang.ref.ReferenceQueueLock)
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=0x15464400 nid=0x2c44 in Object.wait() [0x04fff000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x05005f68> (a java.lang.ref.Reference
L
o
c
k
)
a
t
j
a
v
a
.
l
a
n
g
.
O
b
j
e
c
t
.
w
a
i
t
(
O
b
j
e
c
t
.
j
a
v
a
:
502
)
a
t
j
a
v
a
.
l
a
n
g
.
r
e
f
.
R
e
f
e
r
e
n
c
e
.
t
r
y
H
a
n
d
l
e
P
e
n
d
i
n
g
(
R
e
f
e
r
e
n
c
e
.
j
a
v
a
:
191
)
−
l
o
c
k
e
d
<
0
x
05005
f
68
>
(
a
j
a
v
a
.
l
a
n
g
.
r
e
f
.
R
e
f
e
r
e
n
c
e
Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x05005f68> (a java.lang.ref.Reference
Lock)atjava.lang.Object.wait(Object.java:502)atjava.lang.ref.Reference.tryHandlePending(Reference.java:191)−locked<0x05005f68>(ajava.lang.ref.ReferenceLock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
“VM Thread” os_prio=2 tid=0x02f1d800 nid=0x29c runnable
“VM Periodic Task Thread” os_prio=2 tid=0x15508400 nid=0x2320 waiting on condition
JNI global references: 33
Found one Java-level deadlock:
“ThreadBBB”:
waiting to lock monitor 0x15477204 (object 0x051a67f0, a java.lang.String),
which is held by “ThreadAAA”
“ThreadAAA”:
waiting to lock monitor 0x15478c44 (object 0x051a6818, a java.lang.String),
which is held by “ThreadBBB”
Java stack information for the threads listed above:
“ThreadBBB”:
at com.zhangye.HoldLockThread.run(DeadLockDemo.java:26)
- waiting to lock <0x051a67f0> (a java.lang.String)
- locked <0x051a6818> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
“ThreadAAA”:
at com.zhangye.HoldLockThread.run(DeadLockDemo.java:26)
- waiting to lock <0x051a6818> (a java.lang.String)
- locked <0x051a67f0> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
`