全屏

11.5.3 死锁及解决方案


【专业IT培训机构,真正零首付入学www.bjsxt.com


死锁的概念

      “死锁”指的是:

      多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。

      因此, 某一个同步块需要同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。下面案例中,“化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。那么,实际运行时,“小丫的化妆线程”拥有了“镜子对象”,“大丫的化妆线程”拥有了“口红对象”,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的“死锁状态”。

【示例11-11】死锁问题演示

class Lipstick {//口红类

}
class Mirror {//镜子类

}
class Makeup extends Thread {//化妆类继承了Thread类
	int flag;
	String girl;
	static Lipstick lipstick = new Lipstick();
	static Mirror mirror = new Mirror();

	@Override
	public void run() {
		// TODO Auto-generated method stub
		doMakeup();
	}

	void doMakeup() {
		if (flag == 0) {
			synchronized (lipstick) {//需要得到口红的“锁”;
				System.out.println(girl + "拿着口红!");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				synchronized (mirror) {//需要得到镜子的“锁”;
					System.out.println(girl + "拿着镜子!");
				}

			}
		} else {
			synchronized (mirror) {
				System.out.println(girl + "拿着镜子!");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized (lipstick) {
					System.out.println(girl + "拿着口红!");
				}
			}
		}
	}

}

public class TestDeadLock {
	public static void main(String[] args) {
		Makeup m1 = new Makeup();//大丫的化妆线程;
		m1.girl = "大丫";
		m1.flag = 0;
		Makeup m2 = new Makeup();//小丫的化妆线程;
		m2.girl = "小丫";
		m2.flag = 1;
		m1.start();
		m2.start();
	}
}

      执行结果如图11-14所示(两线程都在等对方的资源,都处于停滞状态):

图11-14示例11-11运行效果图.png

图11-14示例11-11运行效果图

死锁的解决方法

      死锁是由于“同步块需要同时持有多个对象锁造成”的,要解决这个问题,思路很简单,就是:同一个代码块,不要同时持有两个对象锁。 如上面的死锁案例,修改成示例10-11所示。

【示例11-12】死锁问题的解决

class Lipstick {//口红类

}
class Mirror {//镜子类

}
class Makeup extends Thread {//化妆类继承了Thread类
	int flag;
	String girl;
	static Lipstick lipstick = new Lipstick();
	static Mirror mirror = new Mirror();

	@Override
	public void run() {
		// TODO Auto-generated method stub
		doMakeup();
	}

	void doMakeup() {
		if (flag == 0) {
			synchronized (lipstick) {
				System.out.println(girl + "拿着口红!");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
			synchronized (mirror) {
				System.out.println(girl + "拿着镜子!");
			}
		} else {
			synchronized (mirror) {
				System.out.println(girl + "拿着镜子!");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			synchronized (lipstick) {
				System.out.println(girl + "拿着口红!");
			}
		}
	}
}

public class TestDeadLock {
	public static void main(String[] args) {
		Makeup m1 = new Makeup();// 大丫的化妆线程;
		m1.girl = "大丫";
		m1.flag = 0;
		Makeup m2 = new Makeup();// 小丫的化妆线程;
		m2.girl = "小丫";
		m2.flag = 1;
		m1.start();
		m2.start();
	}
}

      执行结果如图11-15和图11-16所示(两线程都可以得到需要的资源,程序正常运行结束):

图11-15示例11-12运行效果图1.png

图11-15示例11-12运行效果图1

图11-16示例11-12运行效果图2.png

图11-16示例11-12运行效果图2

分类导航
点击按住视频可拖动

缩小

关闭

  • 正在学习
  • 北京总部地址:北京市海淀区西三旗街道建材城西路中腾建华商务大厦东侧二层尚学堂
  • 咨询电话:400-009-1906 010-56233821
  • Copyright 2007-2015 北京尚学堂科技有限公司
  • 京ICP备13018289号-1 京公网安备11010802015183