死锁的原因
首先,产生死锁需要两个锁对象(假设A,B),两个线程同时运行,并使用两个锁对象。简单的说就是锁A等待锁B释放,而锁B等待锁A释放,这样就产生了所谓的死锁。当然产生死锁的机率并不是100%,而是有一定的机率;原因是CPU在线程之间切换是没有规律的,所以产生死锁,具体看CPU的调度。请看下面实现代码,再进一步剖析:
public class DieLock {
public static final Object LOCK_A = new Object();
public static final Object LOCK_B = new Object();
public static void main(String[] args) {
// 线程一
new Thread(() ->{
System.out.println("Thread a starter");
synchronized (LOCK_A) {
System.out.println("Thread a: into lock a!");
synchronized (LOCK_B) {
System.out.println("Thread a: into lock b!");
}
System.out.println("Thread a: release lock b!");
}
System.out.println("Thread a: release lock a!");
}).start();
// 线程二
new Thread(() ->{
System.out.println("Thread b starter");
synchronized (LOCK_B) {
System.out.println("Thread b: into lock b!");
synchronized (LOCK_A) {
System.out.println("Thread b: into lock a!");
}
System.out.println("Thread b: release lock a!");
}
System.out.println("Thread b: release lock b!");
}).start();
}
}
分析
-
首先定义两个锁对象,在java中所有对象都可以做锁对象,这里选择Object:LOCK_A,LOCK_B。
-
启动了两个线程,两个线程中都有两个同步锁,第一个是锁B在锁A的里面,第二个是锁A在锁B的里面,就是两个锁交叉使用。也就是两个同步代码块,在执行进入到代码块时,锁对象已经被锁住,代码块执行完锁对象释放。
-
大家都知道CPU在线程之间随机快速切换,我们分析这段代码看出现死锁的情况:
- 当第一个线程执行到第一个同步代码块时,LOCK_A对象已经被锁住;CPU快速切换到第二个线程,执行第一个代码块LOCK_B对象被锁住。
- CPU又切回到第一个线程,程序继续执行,第一个线程现在要执行第二个同步代码块,此时程序中LOCK_B对象已经被锁住,无法往下面执行;CPU切换到线程二,同理往下执行,而LOCK_A也被锁住了。此时:两个线程相互等待对方的锁释放,两边都释放不了,就是产生了死锁现象。
-
以上是个人拙见,若有不对之处,感谢指正,感谢阅读.
网友评论