位置:首页 > Java > 死锁问题原因分析与常见解决方法

死锁问题原因分析与常见解决方法

时间:2026-08-15  |  作者:骑光打字机  |  阅读:0

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

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

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

…………

什么是死锁

这个场景的结局其实不难猜:两个人最后谁也吃不上饭。

放到这个例子里,中国人和美国人可以看作两个不同的线程,筷子和刀叉则对应两把锁。

问题就出在这里——两个线程运行时都在等对方先释放手里的锁。结果彼此僵住,程序也就停在那里不动了,这种情况就叫作死锁。

接下来,就用中国人和美国人吃饭这个案例,来把死锁问题具体模拟出来,见文件1。

文件1 Example15.ja va

 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所示。

死锁问题原因分析与常见解决方法_wishdown.com

图1 运行结果

死锁是如何产生的

在文件1里,创建了两个线程,名字分别是Chinese和American。

它们会各自进入run()方法里if和else对应的同步代码块。

  • Chinese线程先拿到了chopsticks锁,接下来还得再拿到knifeAndFork锁,整个执行过程才能结束。
  • American线程正好相反,它先持有knifeAndFork锁,之后又必须获取chopsticks锁才能继续往下走。

结果就是,两个线程都在等对方手里的那把“锁”。

可谁也不肯先释放自己已经占有的资源,局面一下子僵住了。

最终,这两个线程都会进入挂起状态,也就形成了图1所示的死锁。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多