栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

同步方法中的同步块

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

同步方法中的同步块

在您的示例中,该方法 同时 锁定了

Foo
和的实例
bar
。其他方法可能仅锁定对象的实例
Foo
对象
bar

因此,是的,这完全取决于他们在做什么。大概

bar
可以保护一些较小的数据子集,并且某些方法只需要锁定就
bar
可以以线程安全的方式执行其操作。

是什么
synchronized

synchronized
(在方法上或在语句中)创建互斥区(
关键部分,
或者对于Java特别是
可重入互斥体

)。线程进入关键部分的“关键”是
synchronized
语句‡中使用的对象引用。在使用同一密钥的所有块中,一次只能有一个线程(递归)“拥有”该“密钥”;也就是说,一次只能有一个线程可以输入
synchronized
给定对象引用上的任何块。

这样的关键部分只是防止您在块内执行的 操作
(变量读/写)与锁定同一对象引用的所有其他关键部分中的任何其他操作同时发生。(它不会自动保护对象内的所有变量)。

在Java中,这样的关键部分还会
合同
之前 创建一个
偶然事件

举个例子

作为一个人为的例子†:

public class Foo {    final Bar bar = new Bar();    private int instanceCounter = 0;    private int barCounter = 0;    public synchronized void incrementBarCounterIfAllowed() {        synchronized (bar) { if (instanceCounter < 10) barCounter++;        }    }    public synchronized void incrementClassCounter() {        instanceCounter++;    }    public void incrementBarCounter() {        synchronized (bar) { barCounter++;        }    }}

实例变量是否是私有的与这种方法是否适用无关紧要。在单个类中,您可以有多个锁对象,每个锁对象都保护自己的数据集。

但是这样做的风险是,你必须是 非常 严格的编码规范,以防止死锁通过在不同的地方不同的顺序锁两把锁。例如,使用上面的代码,然后从代码中的其他位置进行操作:

synchronized(myFoo.bar) {  myFoo.incrementClassCounter();}

您可能会为此

incrementBarCounterIfAllowed()
方法陷入僵局

请注意,这

barCounter
可能是
Bar
etc等的实例变量-为了简洁起见,我避免了这样做。

‡对于

synchronized
方法,该引用是对类实例的引用(或
Class<?>
static
方法的类的引用)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/454719.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号