阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

死锁

28次阅读
没有评论

共计 1362 个字符,预计需要花费 4 分钟才能阅读完成。

Java 的线程锁是可重入的锁。

什么是可重入的锁?我们还是来看例子:

public class Counter {private int count = 0;

    public synchronized void add(int n) {if (n < 0) {dec(-n);
        } else {count += n;}
    }

    public synchronized void dec(int n) {count += n;}
}

观察 synchronized 修饰的 add() 方法,一旦线程执行到 add() 方法内部,说明它已经获取了当前实例的 this 锁。如果传入的 n < 0,将在add() 方法内部调用 dec() 方法。由于 dec() 方法也需要获取 this 锁,现在问题来了:

对同一个线程,能否在获取到锁以后继续获取同一个锁?

答案是肯定的。JVM 允许同一个线程重复获取同一个锁,这种能被同一个线程反复获取的锁,就叫做 可重入锁

由于 Java 的线程锁是可重入锁,所以,获取锁的时候,不但要判断是否是第一次获取,还要记录这是第几次获取。每获取一次锁,记录 +1,每退出 synchronized 块,记录 -1,减到 0 的时候,才会真正释放锁。

死锁

一个线程可以获取一个锁后,再继续获取另一个锁。例如:

public void add(int m) {synchronized(lockA) {// 获得 lockA 的锁
        this.value += m;
        synchronized(lockB) {// 获得 lockB 的锁
            this.another += m;
        } // 释放 lockB 的锁
    } // 释放 lockA 的锁
}

public void dec(int m) {synchronized(lockB) {// 获得 lockB 的锁
        this.another -= m;
        synchronized(lockA) {// 获得 lockA 的锁
            this.value -= m;
        } // 释放 lockA 的锁
    } // 释放 lockB 的锁
}

在获取多个锁的时候,不同线程获取多个不同对象的锁可能导致死锁。对于上述代码,线程 1 和线程 2 如果分别执行 add()dec()方法时:

  • 线程 1:进入add(),获得lockA
  • 线程 2:进入dec(),获得lockB

随后:

  • 线程 1:准备获得lockB,失败,等待中;
  • 线程 2:准备获得lockA,失败,等待中。

此时,两个线程各自持有不同的锁,然后各自试图获取对方手里的锁,造成了双方无限等待下去,这就是死锁。

死锁发生后,没有任何机制能解除死锁,只能强制结束 JVM 进程。

因此,在编写多线程应用时,要特别注意防止死锁。因为死锁一旦形成,就只能强制结束进程。

那么我们应该如何避免死锁呢?答案是:线程获取锁的顺序要一致。即严格按照先获取 lockA,再获取lockB 的顺序,改写 dec() 方法如下:

public void dec(int m) {synchronized(lockA) {// 获得 lockA 的锁
        this.value -= m;
        synchronized(lockB) {// 获得 lockB 的锁
            this.another -= m;
        } // 释放 lockB 的锁
    } // 释放 lockA 的锁
}

练习

请观察死锁的代码输出,然后修复。

下载练习

小结

Java 的 synchronized 锁是可重入锁;

死锁产生的条件是多线程各自持有不同的锁,并互相试图获取对方已持有的锁,导致无限等待;

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

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计1362字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中