首页 > 解决方案 > 同步方法的锁定行为

问题描述

一位开发人员与我争辩说,如果我们从另一个 objectA 中的同步方法调用 objectB 中的同步方法,则在 objectB 上获取对象锁定没有额外成本,因为我们已经在 objectA 上锁定。我该如何反驳?

开发人员理论 - “当您调用同步方法时,线程获取该方法中使用的所有对象的锁定。”

class ObjectA {

public synchronized void methodA() {
  methodB();
  // do something else
}

}

class ObjectB {

public synchronized void methodB() {
  // do something
}

}

标签: javasynchronization

解决方案


告诉你的开发人员:

执行静态同步方法的线程持有类的锁,执行静态同步方法的线程持有调用该方法的对象的锁。(这两个锁是不同的,这些线程不会互相阻塞)。

例如:

public class Counter {
    private int count = 0;
    public void increment() {
       synchronized (this) {
       count++;
    }
}
public int getCount() {
    synchronized (this) {
        return count;
    }
}
}

每个创建的 Java 对象,包括每个加载的类,都有一个关联的锁或监视器。

将代码放在同步块中会使编译器在执行代码之前附加指令以获取指定对象上的锁,然后释放它(因为代码正常完成或异常完成)。

在获取锁和释放锁之间,线程被称为“拥有”锁。在线程 A 想要获取锁的时候,如果线程 B 已经拥有它,那么线程 A 必须等待线程 B 释放它。

在您的情况下,将在 ObjectB 类的对象上调用methodB () ,因为它是一个非静态方法。

因此,在进入methodB()时,只要线程看到methodB() 是同步的,就会拥有对ObjectB类的对象(正在调用该方法的对象)的锁。


推荐阅读