死锁
死锁是指多个线程拥有资源,并且都需要对方资源,自己的资源又不释放,此时就造成了死锁。
产生死锁的四个条件
- 一个资源自能被一个线程使用
- 一个线程因为获取资源被阻塞,不释放自己的资源
- 线程获取资源在未使用完之前,不能被强行剥夺
- 若干线程形成一个头尾相连的环,去获取其它线程的资源
我们只需要让一个条件不满足,就避免了死锁。
public class DeadLock {
public static void main(String[] args) {
//创建一个灰姑娘
MakeUp cinderella=new MakeUp(1,"灰姑娘");
//创建一个白雪公主
MakeUp snowWhite=new MakeUp(2,"白雪公主");
cinderella.start();
snowWhite.start();
}
}
//镜子
class Mirror{}
//口红
class Lipstick{}
//化妆
class MakeUp extends Thread{
//变量设置为静态资源,保证锁的是同一对象
private static Mirror mirror=new Mirror();
private static Lipstick lipstick=new Lipstick();
//选择的物品,1表示镜子,2表示口红
private int choice;
public MakeUp(int choice,String name) {
super(name);
this.choice = choice;
}
@Override
public void run() {
makeUp();
}
public void makeUp(){
//如果有镜子
if(choice==1){
synchronized (mirror){
System.out.println(Thread.currentThread().getName()+"需要口红");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//需要口红
synchronized (lipstick){
System.out.println(Thread.currentThread().getName()+"获得口红");
}
}
}
//如果有口红
else {
synchronized (lipstick){
System.out.println(Thread.currentThread().getName()+"需要镜子");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//需要镜子
synchronized (mirror){
System.out.println(Thread.currentThread().getName()+"获得镜子");
}
}
}
}
}
上图代码灰姑娘拥有镜子需要口红,白雪公主有口红需要镜子,她们又都不给对方,就造成了死锁的情况,程序就会卡住不执行。
我们只需要将里面的同步块放在外面,不嵌套锁,就避免了死锁的发生,具体代码如下图所示。
public void makeUp(){
//如果有镜子
if(choice==1){
synchronized (mirror){
System.out.println(Thread.currentThread().getName()+"需要口红");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//需要口红
synchronized (lipstick){
System.out.println(Thread.currentThread().getName()+"获得口红");
}
}
//如果有口红
else {
synchronized (lipstick){
System.out.println(Thread.currentThread().getName()+"需要镜子");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//需要镜子
synchronized (mirror){
System.out.println(Thread.currentThread().getName()+"获得镜子");
}
}
}