线程的死锁

99 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

大家好,我是尚影嫣🌷,一名Java后端程序媛。如果您喜欢我的文章,欢迎点赞➕关注❤️,让我们一起成为更好的我们~

线程的死锁

线程死锁是指:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。死锁后不会出现异常,不会出现提示,由于线程被无限期地阻塞,因此程序无法正常终止。

产生死锁的四个必要条件

1)互斥条件:一个资源每次只能被一个进程使用。

2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

3)不剥夺条件:进程已获得的资源,在末使用完之前不能强行剥夺。

4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

处理死锁的方法

预防死锁;避免死锁;检测死锁;解除死锁。

如何避免线程死锁?

  1. 破坏请求与保持条件 :一次性申请所有的资源。
  2. 破坏不剥夺条件 :占用部分资源的线程在进一步申请其他资源时,如果没申请成功,可以主动释放它占有的资源。
  3. 破坏循环等待条件 :靠按序申请资源来预防,破坏循环等待条件。

死锁示例:

package yanf.thread;

public class Deadlock {
    public static void main(String[] args) {
        Culprit c = new Culprit();
        Police p = new Police();
        new MyThread(c, p).start();
    }

    static class MyThread extends Thread {
        private Culprit c;
        private Police p;

        public MyThread(Culprit c, Police p) {
            this.c = c;
            this.p = p;
        }

        @Override
        public void run() {
            p.say(c);
        }
    }

    static class Culprit {
        public void say(Police p) {
            System.out.println("罪犯:你放了我,我放了人质!");
            p.response();
        }

        public void response() {
            System.out.println("罪犯被放走了,罪犯也放了人质");
        }
    }

    static class Police {
        public void say(Culprit c) {
            System.out.println("警察:你放了人质,我放了你!");
            c.response();
        }

        public void response() {
            System.out.println("罪犯放了人质,罪犯逃走了");
        }

    }
}

运行结果:

image.png