目录
死锁问题
死锁:锁对象的循环等待问题,使用jconsole来检查死锁
死锁是一种严重的 BUG。导致一个程序的线程 "卡死",无法正常工作!
/** * 死锁 */ public class DeadLockTest { public static void main(String[] args) { Object projectLock = new Object(); Object songLock = new Object(); Thread t1 = new Thread(() -> { synchronized (songLock) { System.out.println("先唱歌,再写项目"); try { Thread.sleep(300); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (projectLock) { System.out.println("歌唱完了,可以写项目了"); } } }, "A"); Thread t2 = new Thread(() -> { synchronized (projectLock) { System.out.println("先写项目,再唱"); try { Thread.sleep(300); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (songLock) { System.out.println("写完项目,来一首歌"); } } }, "B"); t1.start(); t2.start(); } }
使用jconsole检查死锁
哲学家就餐问题
有个桌子,围着一圈哲学家,桌子中间放着一盘意大利面。
每个哲学家两两之间,放着一根筷子。
每个哲学家只做两件事:思考人生 或者 吃面条。
思考人生的时候就会放下筷子,吃面条就会拿起左右两边的筷子(先拿起左边, 再拿起右边)。
如果哲学家发现筷子拿不起来了(被别人占用了),就会阻塞等待。[关键点] 假设同一时刻, 五个哲学家同时拿起左手边的筷子,然后再尝试拿右手的筷子,就会发现右手的筷子都被占用了。由于哲学家们互不相让,这个时候就形成了死锁 。
避免死锁
解除死锁,只需要破坏这个循环等待的条件即可,多个线程获取资源不要成环即可。
各让一步,避免死锁。
/** * 避免死锁 */ public class DeadLockTest { public static void main(String[] args) { Object projectLock = new Object(); Object songLock = new Object(); Thread t1 = new Thread(() -> { synchronized (projectLock) { System.out.println("歌唱完了,可以写项目了"); synchronized (songLock) { System.out.println("先唱歌,再写项目√"); try { Thread.sleep(300); } catch (InterruptedException e) { throw new RuntimeException(e); } } } }, "A"); Thread t2 = new Thread(() -> { synchronized (projectLock) { System.out.println("先写项目,再唱"); try { Thread.sleep(300); } catch (InterruptedException e) { throw new RuntimeException(e); } synchronized (songLock) { System.out.println("写完项目,来一首歌"); } } }, "B"); t1.start(); t2.start(); } }