死锁及如何解决死锁

文章通过代码示例解释了死锁发生的原因,即线程间不同步获取锁导致无限等待。为了避免死锁,建议保持所有线程获取锁的顺序一致。示例中展示了两个线程尝试以不同顺序获取两个锁,导致死锁,而修正后的代码则遵循相同的锁获取顺序,从而避免了死锁问题。
摘要由CSDN通过智能技术生成

死锁的原因

多线程各自持有不同的锁,并互相试图获取对方已持有的锁,导致无限等待。死锁发生后,没有任何机制能解除死锁,只能强制结束JVM进程。

如何避免死锁

避免死锁的方法是多线程获取锁的顺序要一致。

代码示例

  • 这种情况会造成死锁:线程1在试图获取线程2已经获取并未释放的锁

  • 在这里插入图片描述

  • 什么时候会释放锁:synchronized代码块结束之后才会释放由synchronized获取的锁

package org.meituan.javalearn.thread;

/**
 * @projectName: codebetter
 * @package: org.meituan.javalearn.thread
 * @className: DeadLock
 * @author: fangjiayueyuan
 * @description: 死锁
 * @date: 2023/5/4 上午10:30
 * @version: 1.0
 */
public class DeadLock {
    static final Object LOCK_A = new Object();
    static final Object LOCK_B = new Object();
    public static void main(String[] args) {
        new Thread1().start();
        new Thread2().start();
    }
    static void sleep1s() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
class Thread1 extends Thread {

    public void run() {
        System.out.println("Thread-1: try get lock A...");
        synchronized (DeadLock.LOCK_A) {
            System.out.println("Thread-1: lock A got.");
            DeadLock.sleep1s();
            System.out.println("Thread-1: try get lock B...");
            synchronized (DeadLock.LOCK_B) {
                System.out.println("Thread-1: lock B got.");
                DeadLock.sleep1s();
            }
            System.out.println("Thread-1: lock B released.");
        }
        System.out.println("Thread-1: lock A released.");
    }
}

class Thread2 extends Thread {

    public void run() {
        System.out.println("Thread-2: try get lock B...");
        synchronized (DeadLock.LOCK_B) {
            System.out.println("Thread-2: lock B got.");
            DeadLock.sleep1s();
            System.out.println("Thread-2: try get lock A...");
            synchronized (DeadLock.LOCK_A) {
                System.out.println("Thread-2: lock A got.");
                DeadLock.sleep1s();
            }
            System.out.println("Thread-2: lock A released.");
        }
        System.out.println("Thread-2: lock B released.");
    }
}
  • 改写代码:按照相同的顺序去获取锁,避免死锁
package org.meituan.javalearn.thread;

/**
 * @projectName: codebetter
 * @package: org.meituan.javalearn.thread
 * @className: DeadLock
 * @author: fangjiayueyuan
 * @description: 死锁
 * @date: 2023/5/4 上午10:30
 * @version: 1.0
 */
public class DeadLock {
    static final Object LOCK_A = new Object();
    static final Object LOCK_B = new Object();
    public static void main(String[] args) {
        new Thread1().start();
        new Thread2().start();
    }
    static void sleep1s() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
class Thread1 extends Thread {

    public void run() {
        System.out.println("Thread-1: try get lock A...");
        synchronized (DeadLock.LOCK_A) {
            System.out.println("Thread-1: lock A got.");
            DeadLock.sleep1s();
            System.out.println("Thread-1: try get lock B...");
            synchronized (DeadLock.LOCK_B) {
                System.out.println("Thread-1: lock B got.");
                DeadLock.sleep1s();
            }
            System.out.println("Thread-1: lock B released.");
        }
        System.out.println("Thread-1: lock A released.");
    }
}

class Thread2 extends Thread {

    public void run() {
        System.out.println("Thread-2: try get lock A...");
        synchronized (DeadLock.LOCK_A) {
            System.out.println("Thread-2: lock A got.");
            DeadLock.sleep1s();
            System.out.println("Thread-2: try get lock B...");
            synchronized (DeadLock.LOCK_B) {
                System.out.println("Thread-2: lock B got.");
                DeadLock.sleep1s();
            }
            System.out.println("Thread-2: lock B released.");
        }
        System.out.println("Thread-2: lock A released.");
    }
}


效果图:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值