一线程持有a资源,需要获取b资源才释放a资源。
二线程持有b资源,需要获取a资源才释放b资源。
造成死锁。
下面举个例子:
两个女人化妆,需要镜子和口红,两个人一个先拿镜子,再拿口红,另一个先拿口红,再拿镜子
/**
* @author TEDU
* 死锁出现的情况多是锁套锁。
*/
public class DeadLock {
public static void main(String[] args) {
MakeUp m1 = new MakeUp("小红",1);
MakeUp m2 = new MakeUp("小丽",2);
m1.start();
m2.start();
}
}
//镜子
class Mirror{
}
//口红
class Lipstick{
}
//化妆
class MakeUp extends Thread{
//这里是静态修饰,保证她们拿到的是同一个镜子和口红
private static Mirror mirror = new Mirror();
private static Lipstick lipstick = new Lipstick();
private String name;
private int choice;
public MakeUp(String name,int choice) {
this.name = name;
this.choice = choice;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
makeUp(choice);
}
public void makeUp(int choice) {
if(choice == 1) {
synchronized (mirror){
//先拿了镜子
System.out.println(name+"拿了镜子");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (lipstick) {//写在锁中的锁:拿口红
//再拿了镜子
System.out.println(name+"拿了口红");
}
}
}else {
synchronized (lipstick){
//先拿了口红
System.out.println(name+"拿了口红");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (mirror) {//写在锁中的锁:拿镜子
//再拿了镜子
System.out.println(name+"拿了镜子");
}
}
}
}
}
这个程序就会造成死锁。
本例解决方法:放下已有资源(解锁),再获取另一个资源。
也就是将锁套锁解除,将写在同步块里的同步块拿出来并列即可。
if(choice == 1) {
synchronized (mirror){
//先拿了镜子
System.out.println(name+"拿了镜子");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
synchronized (lipstick) {//锁单独写出来:拿口红
//再拿了镜子
System.out.println(name+"拿了口红");
}
}