You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程中线程获取单个对象锁是否等同于持有该类所有对象的锁?

问题修正

原问题未明确访问的是实例的需要持有对象锁的同步资源,如果是访问普通非同步属性/方法,本来就不会触发锁竞争,因此优化后的严谨表述为:

在基于对象锁实现同步的多线程场景(以Java为例)中,若某一线程已经获取类A的实例a1的对象锁,此时另一个线程新建类A的实例a2,并尝试访问a2的同步方法/需要持有a2对象锁的代码块,是否会受到前者持有的锁的限制?

解答
  • 正常情况下完全不会受到限制。对象锁是和具体实例绑定的,每个实例的对象锁都是独立的,互不影响。
  • 线程持有a1的对象锁时,只会阻塞其他尝试获取a1锁的操作,和其他实例的锁没有任何关联。线程2操作a2的同步资源时,只需要竞争a2自己的对象锁即可,不需要等a1的锁释放。
  • 只有一种特殊情况会出现跨实例的锁限制:你用的是类锁而非实例对象锁,比如同步方法加了static修饰,或者同步块锁定的是A.class全局类对象,此时所有该类的实例同步资源都共用同一把类锁,才会互相阻塞。

可以参考下面的测试代码验证结论:

public class LockTest {
    // 实例级同步方法,锁为当前类实例对象
    public synchronized void instanceSync() {
        System.out.println(Thread.currentThread().getName() + " 开始执行实例同步方法");
        try {
            // 模拟业务执行2秒
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 执行结束");
    }

    public static void main(String[] args) throws InterruptedException {
        LockTest instance1 = new LockTest();
        // 线程1先拿到instance1的锁,执行2秒
        new Thread(instance1::instanceSync, "线程1").start();
        // 保证线程1先启动并拿到锁
        Thread.sleep(100);

        LockTest instance2 = new LockTest();
        // 线程2操作instance2,不会被阻塞
        new Thread(instance2::instanceSync, "线程2").start();
    }
}

运行代码后会看到两个线程的「开始执行」日志几乎同时打印,间隔远小于2秒,验证实例锁互不干扰的结论。

内容的提问来源于stack exchange,提问作者chathala anil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 20:09:03