前言
本篇博文是对Java多线程中的死锁的实现介绍。
多线程的死锁
1.死锁的原因:
首先,产生死锁需要的两个锁对象(假设A,B),当两个线程同时运行时,并同时使用了两个锁对象;简单说就是锁A等待锁B释放,而锁B也在等待锁A释放,这样就产生了所谓的死锁,当然死锁的几率并不是百分之百,而是有一定几率的;原因的CPU在线程之间切换是没有规律的,所以产生死锁,具体看CPU的调节度
2.使用一个例子来更深刻的了解死锁
演示死锁:
比如我现在有两个锁对象LOCK_A,LOCK_B(在Java中所有的对象都是可以做为锁对象的这里的两个锁对象都是Object),我把两个锁对象比喻成两根筷子,只有拿到两个筷子时才能进食(对于一个线程而言同时满足)
3.代码
package com
.jimmy
.demo
;
public class Deadlock {
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 start");
synchronized (LOCK_A
) {
System
.out
.println("Thread a :拿到筷子A,等待筷子B");
synchronized (LOCK_B
) {
System
.out
.println("Thread a : 拿到筷子B,开始进食");
}
}
}).start();
new Thread(() -> {
System
.out
.println("Thread b start");
synchronized (LOCK_B
) {
System
.out
.println("Thread b :拿到筷子B,等待筷子A");
synchronized (LOCK_A
) {
System
.out
.println("Thread b :拿到筷子A,开始进食");
}
}
}).start();
}
}
3.1.代码分析
启动了两个线程,两个线程中都有两个同步锁,第一个线程时锁B在锁A里面,第二个线程时锁A在锁B里面,两个锁交叉使用。在执行到代码块时,锁对象已经被锁住,代码块执行完锁对象释放
3.2.测试结果
注意:不是每次运行都会出现死锁现象,这是本人运行多次才出现的死锁现象
3.3.根据测试结果分析
CPU时在线程之间高速切换的,我们来分析一下这段代码出现的死锁情况
1.当第一个线程执行到第一个同步代码块时,LOCK_A对象已经被锁住;CPU快速切换到第二个线程,执行第一个代码块LOCK_B对象被锁住
2.CPU又切回到第一个线程,程序无法执行,第一个线程现在要执行第二个同步代码块,此时LOCK_B对象已经被锁住,无法往下面执行;CPU切换到线程二,同理往下执行,而LOCK_A也被锁住,此时:两个线程相互等待对方锁释放,而两边都释放不了,就产生了死锁