多线程之死锁分析
Posted Java硅谷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程之死锁分析相关的知识,希望对你有一定的参考价值。
在多线程操作过程中,我们难免会遇到资源加锁,保证共享资源的安全性,不免有时会遇到死锁的问题。现在我们就一个简单的实例代码对死锁问题进行剖析,抛砖引玉。
案例:
public class OtherService {
DeadLock deadLock;
public void setDeadLock(DeadLock deadLock){
this.deadLock = deadLock;
}
private final Object LOCK = new Object();
public void s1(){
synchronized (LOCK){
System.out.println("s1----------------------------");
}
}
public void s2(){
synchronized (LOCK){
System.out.println("s2----------------------------");
deadLock.m2();
}
}
}
public class DeadLock {
private OtherService otherService;
public DeadLock(OtherService otherService){
this.otherService = otherService;
}
private final Object LOCK = new Object();
public void m1(){
synchronized (LOCK){
System.out.println("m1-----------------------");
otherService.s1();
}
}
public void m2(){
synchronized (LOCK){
System.out.println("m2-----------------");
}
}
}
测试类:
public class DeadLockTest {
public static void main(String[] args) {
OtherService otherService = new OtherService();
DeadLock deadLock = new DeadLock(otherService);
otherService.setDeadLock(deadLock);
new Thread(()->{
while (true){
deadLock.m1();
}
}).start();
new Thread(()->{
while (true){
otherService.s2();
}
}).start();
}
}
观察测试案例,可以知道,我们测试类中对OtherService和DeadLock相互持有,模拟一个死锁状态,当两个线程执行到某一个状态的时候,OtherService和DeadLock就会达到互斥的状态,占锁不放并且想要获取的锁拿不到,从而达到死锁状态。
分析:
我们可以利用jdk的命令查看线程的状态:
jstack [进程号]
F:\Study_>jstack 2788
2018-04-10 13:04:54
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode):
"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000004c7e000 nid=0x196c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #12 prio=5 os_prio=0 tid=0x000000001b793000 nid=0x17d0 waiting for monitor entry [0x000000001c1de000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.thread.thred.dead.DeadLock.m2(DeadLock.java:21)
- waiting to lock <0x00000000d5d93040> (a java.lang.Object)
at com.thread.thred.dead.OtherService.s2(OtherService.java:25)
- locked <0x00000000d5d90558> (a java.lang.Object)
at com.thread.thred.dead.DeadLockTest.lambda$main$1(DeadLockTest.java:18)
at com.thread.thred.dead.DeadLockTest$$Lambda$2/1831932724.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"Thread-0" #11 prio=5 os_prio=0 tid=0x000000001b792800 nid=0x226c waiting for monitor entry [0x000000001c0df000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.thread.thred.dead.OtherService.s1(OtherService.java:17)
- waiting to lock <0x00000000d5d90558> (a java.lang.Object)
at com.thread.thred.dead.DeadLock.m1(DeadLock.java:15)
- locked <0x00000000d5d93040> (a java.lang.Object)
at com.thread.thred.dead.DeadLockTest.lambda$main$0(DeadLockTest.java:12)
at com.thread.thred.dead.DeadLockTest$$Lambda$1/990368553.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
从线程状态可以看出,Thread-0和Thread-1已经是死锁状态。
死锁发生的条件是:
互斥条件(Mutual exclusion) :资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):进程已获得了一些资源,但因请求其它资源被阻塞时,对已获得的资源保持不放。
不可抢占条件(No pre-emption) :有些系统资源是不可抢占的,当某个进程已获得这种资源后,系统不能强行收回,只能由进程使用完时自己释放。
循环等待条件(Circular wait) :若干个进程形成环形链,每个都占用对方申请的下一个资源。
以上是关于多线程之死锁分析的主要内容,如果未能解决你的问题,请参考以下文章