java - 同步方法的锁定行为
问题描述
一位开发人员与我争辩说,如果我们从另一个 objectA 中的同步方法调用 objectB 中的同步方法,则在 objectB 上获取对象锁定没有额外成本,因为我们已经在 objectA 上锁定。我该如何反驳?
开发人员理论 - “当您调用同步方法时,线程获取该方法中使用的所有对象的锁定。”
class ObjectA {
public synchronized void methodA() {
methodB();
// do something else
}
}
class ObjectB {
public synchronized void methodB() {
// do something
}
}
解决方案
告诉你的开发人员:
执行静态同步方法的线程持有类的锁,执行非静态同步方法的线程持有调用该方法的对象的锁。(这两个锁是不同的,这些线程不会互相阻塞)。
例如:
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类的对象(正在调用该方法的对象)的锁。
推荐阅读
- angular - 以角度将数据从图像提取到文本
- python - Python,将 1d 数据投影和插值到 3d 网格(头部表面脑电图功率)
- python - Numpy 数组元素与 Float64 的比较
- javascript - 如何使用 Word API/Office JS 实现单词在拼写错误期间显示的红色曲线?
- api - Jmeter中GET请求的可变路径参数
- c# - 组合框列表更改时属性值更改为空(WPF)
- jenkins - 我对 Jenkins Pipeline 脚本有疑问。WorkFlowScript 类没有此类属性
- excel - (xlCellTypeVisible).EntireRow.Delete 转到私有子
- java - 如何使用 android 将数据添加到 SharePoint 列表中?
- javascript - Vue 和 Vue 多选。制作选项以对所选语言做出反应