学科分类
目录
Java基础

死锁问题

有这样一个场景:一个中国人和一个美国人在一起吃饭,美国人拿了中国人的筷子,中国人拿了美国人的刀叉,两个人开始争执不休:

中国人:“你先给我筷子,我再给你刀叉!”

美国人:“你先给我刀叉,我再给你筷子!”

…………

上面场景的结果可想而知,两个人都吃不到饭。这个例子中的中国人和美国人相当于不同的线程,筷子和刀叉就相当于锁。两个线程在运行时都在等待对方的锁,这样便造成了程序的停滞,这种现象称为死锁。接下来通过中国人和美国人吃饭的案例来模拟死锁问题,如文件1所示。

文件1 Example15.java

 1    class DeadLockThread implements Runnable {
 2        // 定义两个不同的锁对象
 3        static Object chopsticks = new Object();
 4        static Object knifeAndFork = new Object();
 5        private boolean flag;
 6        DeadLockThread(boolean flag) {
 7            this.flag = flag;
 8        }
 9        public void run() {
 10            if (flag) {
 11                while (true) {
 12                    // chopsticks锁对象上的同步代码块
 13                    synchronized (chopsticks) { 
 14                        System.out.println(Thread.currentThread().getName()
 15                                             + "---if---chopsticks");
 16                        // knifeAndFork锁对象上的同步代码块
 17                        synchronized (knifeAndFork) { 
 18                        System.out.println(Thread.currentThread().getName()
 19                                            + "---if---knifeAndFork");
 20                        }
 21                    }
 22                }
 23            } else {
 24                while (true) {
 25                    // knifeAndFork锁对象上的同步代码块
 26                    synchronized (knifeAndFork) { 
 27                        System.out.println(Thread.currentThread().getName()
 28                                             + "---else---knifeAndFork");
 29                        // chopsticks锁对象上的同步代码块
 30                        synchronized (chopsticks) { 
 31                        System.out.println(Thread.currentThread().getName() 
 32                                            + "---else---chopsticks");
 33                        }
 34                    }
 35                }
 36            }
 37        }
 38    }
 39    public class Example15 {
 40        public static void main(String[] args) {
 41            // 创建两个DeadLockThread对象
 42            DeadLockThread thread1 = new DeadLockThread(true);
 43            DeadLockThread thread2 = new DeadLockThread(false);
 44            // 创建并开启两个线程
 45            new Thread(thread1, "Chinese").start();
 46            new Thread(thread2, "American").start();
 47        }
 48    }

运行结果如图1所示。

图1 运行结果

文件1中,创建了两个名为Chinese和American的线程,分别执行run()方法中if和else代码块中的同步代码块。Chinese线程中拥有chopsticks锁,只有获得knifeAndFork锁才能执行完毕,而American线程拥有knifeAndFork锁,只有获得chopsticks锁才能执行完毕,两个线程都需要对方所占用的锁,但是都无法释放自己所拥有的锁,于是这两个线程都处于了挂起状态,从而造成了如图1所示的死锁。

点击此处
隐藏目录