synchronized 与死锁

本文探讨了在多线程编程中synchronized关键字的作用及如何引发死锁问题。synchronized确保代码块原子执行,锁定的对象而非代码。死锁通常发生在线程持有资源并请求对方持有的资源,形成环状等待。开发者应谨慎避免这种情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在进行多线程编程时,死锁是我们一定要进行判断和避免的。本篇博客介绍一下synchronized的死锁内容。

synchronized介绍

synchronized是常见的锁。常见用法如下:

synchronized (A) {
    ...
    ...
    ...
}

它可以保证花括号内的所有代码是原子执行的。
但我们要注意的是,sychronized锁定的对象不是代码段。sychronized锁定的实际上是一个类或者对象(A)。每个对象只能由一个线程占用锁。在执行由sychronized包含的代码时,线程会先尝试获取对象的锁再执行代码。

所以我们可以看出,synchronized有关的死锁只需要考虑锁定的对象,而不需要考虑代码行。

这里需要注意的是,synchronized建立的是线程与对象的联系而不是synchronized语句与对象的联系。我们看下面这个例子

	public static void main(String[] args) {
        Integer a = 3;
        synchronized (a) {
            synchronized (a) {
                System.out.println(a);
            }
        }
    }

这份代码试图“我死锁我自己”,但遗憾没能成功,程序会正常进行。原因是进入第二层synchronized语句时,线程已经在第一层获得了a的锁,所以直接继续执行。

死锁情况

多线程的死锁往往可以总结为如下情况:
线程1手握对象A,想获得B的锁;而线程2手握对象B,想获得A的锁,从而发生死锁。

		//线程1
		synchronized (A) {
            ...
            synchronized (B) {
                ...
            }
        }
		//线程2
        synchronized (B) {
            ...
            synchronized (A) {
                ...
            }
        }

实际上这种死锁不仅仅局限在两个线程之间,多个线程之间只要形成一个闭环,就会发生死锁。因此在编写代码时一定要注意检查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值