36 多线程(八)——线程造成死锁

一线程持有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+"拿了口红");
			}
		}

  

 

 

posted @ 2019-12-06 13:42  Scorpicat  阅读(154)  评论(0编辑  收藏  举报