线程死锁

2020-11-30  本文已影响0人  何几时

死锁定义

多个线程各自占用共享资源,都在等待对方线程释放资源来继续运行,某一个同步块内若同时拥有两个以上对象的锁时,就会发生死锁现象

死锁避免方法

产生死锁的四个必要条件

  1. 互斥条件:一个资源每次只能被一个进程使用
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
  3. 不剥夺条件:进程已获得的资源,在未使用时,不能强行剥夺
  4. 循环等待条件:若干进程之间形成一种头尾相接的等待资源关系

化妆例子

// 死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {
    public static void main(String[] args) {
        Makeup g1 = new Makeup(0, "灰姑凉");
        Makeup g2 = new Makeup(1, "白雪公主");

        g1.start();
        g2.start();
    }

}

// 口红
class Lipstick{

}

// 镜子
class Mirror{

}

class Makeup extends Thread{

    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    int choice; // 选择
    String girlName;  // 使用化妆品的人


    public Makeup(int choice, String girlName) {
        this.choice = choice;
        this.girlName = girlName;
    }

    @Override
    public void run() {
        // 化妆
        makeup();
    }

    // 化妆,互相持有对方的锁,就是需要拿到对方的资源
    private void makeup() {
        if (choice==0) {
            synchronized (lipstick) {  // 获得口号的锁
                System.out.println(this.girlName + "获得口红的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (mirror) {
                    System.out.println(this.girlName + "获得镜子的锁");
                }

            }
        }else {
            synchronized (mirror) {  // 获得口号的锁
                System.out.println(this.girlName + "获得镜子的锁");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (lipstick) {
                    System.out.println(this.girlName + "获得口红的锁");
                }

            }
        }
    }
}

改进版本(把同步块内的另一个同步块拿出来)

package demo04_synchronized;

// 死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock1_0 {
    public static void main(String[] args) {
        Makeup01 g1 = new Makeup01(0, "灰姑凉");
        Makeup01 g2 = new Makeup01(1, "白雪公主");

        g1.start();
        g2.start();
    }

}

// 口红
class Lipstick01{

}

// 镜子
class Mirror01{

}

class Makeup01 extends Thread{

    static demo04_synchronized.Lipstick lipstick = new demo04_synchronized.Lipstick();
    static demo04_synchronized.Mirror mirror = new demo04_synchronized.Mirror();

    int choice; // 选择
    String girlName;  // 使用化妆品的人


    public Makeup01(int choice, String girlName) {
        this.choice = choice;
        this.girlName = girlName;
    }

    @Override
    public void run() {
        // 化妆
        makeup();
    }

    // 化妆,互相持有对方的锁,就是需要拿到对方的资源
    private void makeup() {
        if (choice==0) {
            synchronized (lipstick) {  // 获得口号的锁
                System.out.println(this.girlName + "获得口红的锁");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (mirror) {
                System.out.println(this.girlName + "获得镜子的锁");
            }
        }else {
            synchronized (mirror) {  // 获得口号的锁
                System.out.println(this.girlName + "获得镜子的锁");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (lipstick) {
                System.out.println(this.girlName + "获得口红的锁");
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读