Java多线程(10)-死锁的排查、避免与解决

308 阅读1分钟

死锁的发生原因

两个或多个线程之间,分别持有一份资源,并且等待对方释放其手中的资源,就造成了死锁,

就像情侣吵架,都在等对方来找自己,就这么一直僵持着,

著名的文章有哲学家就餐问题,5个哲学家在一个圆桌上,右手边都有一个叉子,但是需要两个叉子才能吃面,当每个哲学家都拿起自己右手边的叉子,再尝试拿左右边的叉子时,已经被上一个人拿起来了,这时候就发生了死锁,没有两个叉子无法吃面~而他们都在等自己左边的人放下叉子。

写一份死锁代码

死锁代码思路,使用两个对象当做锁对象,再使用两个线程,一个先得到锁1,尝试得到锁2,另一个先得到锁2,再尝试得到锁1,

这就发生了死锁,如下代码:

public class Lock {
    static Object lock1 = new Object();
    static Object lock2 = new Object();
    public static void main(String[] args) throws InterruptedException {
        // 得到lock2锁,休眠500毫秒后尝试得到lock1锁
        new Thread(() -> {
            synchronized (lock2) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("我拿到了lock1");
                }
            }
        }).start();
        // 得到lock1锁,休眠500毫秒后尝试得到lock2锁
        synchronized (lock1) {
            Thread.sleep(500);
            synchronized (lock2) {
                System.out.println("我拿到了lock2");
            }
        }
    }
}

可以通过jstack看见,两个线程发生了死锁,在相互僵持着:

image.png