package com.kuang.thread;
import com.sun.org.apache.bcel.internal.generic.NEW;
/**
* @ClassName DeadLock
* @Description 死锁
* @Author 麻虾
* @Date 2021/5/31 22:16 16
* @Version 1.0
*/
//化妆的案例
//死锁:多个线程互相抱着对方需要的资源不释放,然后就一直互相等待,形成僵持
public class DeadLock {
public static void main(String[] args) {
Makeup girl1 = new Makeup(0,"灰姑凉");
Makeup girl2 = new Makeup(1,"白雪公主");
girl1.start();
girl2.start();
}
}
//口红
class Lipstick {}
//镜子
class Mirror {}
class Makeup extends Thread {
//需要的资源只有一份,用static来保证一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;//选择
String girlName;//使用化妆品的人
Makeup(int choice, String girlName) {
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//化妆:互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if (choice == 0) {//第一个人,拿着口红想要镜子
synchronized (lipstick) {//获得口红的锁
System.out.println(this.girlName + "获得口红的锁");
Thread.sleep(1000);
synchronized (mirror) {//一秒钟后去拿镜子
System.out.println(this.girlName + "获得镜子的锁");
}
}
} else {//第二个人,拿着镜子想要口红
synchronized (mirror) {//获得镜子的锁
System.out.println(this.girlName + "获得镜子的锁");
Thread.sleep(2000);
synchronized (lipstick) {//两秒钟后去拿口红的锁
System.out.println(this.girlName + "获得口红的锁");
}
}
}
}
}
以上代码中,一个同步块中同时拥有 “两个及以上对象的锁” 产生死锁:
//化妆:互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if (choice == 0) {//第一个人,拿着口红想要镜子
synchronized (lipstick) {//获得口红的锁
System.out.println(this.girlName + "获得口红的锁");
Thread.sleep(1000);
synchronized (mirror) {//一秒钟后去拿镜子
System.out.println(this.girlName + "获得镜子的锁");
}
}
} else {//第二个人,拿着镜子想要口红
synchronized (mirror) {//获得镜子的锁
System.out.println(this.girlName + "获得镜子的锁");
Thread.sleep(2000);
synchronized (lipstick) {//两秒钟后去拿口红的锁
System.out.println(this.girlName + "获得口红的锁");
}
}
}
}
所以程序一直处于僵持等待状态,灰姑凉拿不到镜子的锁,白雪公主也拿不到口红的锁:
解决:
将同步块中的请求移到外面,使得同步块中只有一个对象的锁,这样即可避免产生死锁:
private void makeup() throws InterruptedException {
if (choice == 0) {//第一个人,拿着口红想要镜子
synchronized (lipstick) {//获得口红的锁
System.out.println(this.girlName + "获得口红的锁");
Thread.sleep(1000);
}
synchronized (mirror) {//一秒钟后去拿镜子
System.out.println(this.girlName + "获得镜子的锁");
}
} else {//第二个人,拿着镜子想要口红
synchronized (mirror) {//获得镜子的锁
System.out.println(this.girlName + "获得镜子的锁");
Thread.sleep(2000);
}
synchronized (lipstick) {//两秒钟后去拿口红的锁
System.out.println(this.girlName + "获得口红的锁");
}
}
}
未产生死锁的结果:
灰姑凉获得口红的锁
白雪公主获得镜子的锁
白雪公主获得口红的锁
灰姑凉获得镜子的锁