package com.demo;
/*
* 同步机制解决了线程安全问题,但同时也引发了新的问题:死锁。
*
* 哲学家就餐问题:
* 5个哲学家,5把叉子,5盘意大利面(意大利面很滑,需要两把叉子才能拿起)大家围绕桌子,进行思考与进食的活动,如下图所示。
* 每个人都需要两个叉子才能吃到面,吃完后将叉子放回原处继续思考;如果每个人都立刻抓住自己左边的叉子,然后等待右边的叉子
* 空出来,同时又不放下已经拿到的叉子,这样每个人都无法得到两个叉子,这样就产生了死锁;
* 每个人都拥有其他人需要的资源,同时又等待其他人拥有的资源,并且每个人在获取所有需要的资源之前都不会放弃已经拥有的资源;
*
* 当多个线程完成功能需要同时获取多个共享资源的时候就可能会产生死锁;
* 如果一个类可能发生死锁,并不意味着每次都会出现死锁,只是有可能发生;
*
* 死锁现象出现的原因:
* 1、存在两个或两个以上的线程;
* 2、存在两个或者两个以上的共享资源;
* 3、每个线程完成功能都需要使用两个或两个以上的共享资源;
*
* 死锁现象的解决方案:没有方案,一旦发生就不能解决。只能尽量避免发生。
*
*/
// 模拟死锁现象:存在两个线程:张三和李四;存在两个共享资源:遥控器和电池;只有同时拿到遥控器和电池才能开启空调;
// 如果张三拿了遥控器,李四拿了电池;然后张三再去拿电池,同时不放弃手上的遥控器;同时李四去拿遥控器,也不愿意放弃
// 手上的电池,那么两个人都在等待,都无法完成功能,这样就产生了死锁;
public class Demo5 extends Thread{
public Demo5(String name) {
super(name);
}
/*
* (non-Javadoc)
* @see java.lang.Thread#run()
* "遥控器"和"电池"一旦创建,就会存在于常量池中,不会再次创建,所以是唯一共享的对象;
*/
@Override
public void run() {
if (Thread.currentThread().getName().equals("张三")){
synchronized ("遥控器") {
System.out.println("张三拿到了遥控器,准备去拿电池。");
synchronized ("电池") {
System.out.println("张三拿到了电池,可以吹空调了。");
}
}
}else if (Thread.currentThread().getName().equals("李四")){
synchronized ("电池") {
System.out.println("李四拿到了电池,准备去拿遥控器。");
synchronized ("遥控器") {
System.out.println("李四拿到了遥控器,可以吹空调了。");
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Demo5 d1 = new Demo5("张三");
d1.start();
Demo5 d2 = new Demo5("李四");
d2.start();
}
}