我继续运行使用双重检查锁定的代码,但我仍然对为什么使用它感到困惑。
我一开始并不知道双重检查锁定被破坏 http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html,当我了解到它时,它为我放大了这个问题:人们为什么首先使用它?比较和交换不是更好吗?
if (field == null)
Interlocked.CompareExchange(ref field, newValue, null);
return field;
(我的问题适用于 C# 和 Java,尽管上面的代码适用于 C#。)
与原子操作相比,双重检查锁定是否具有某种固有的优势?
与原子操作相比,双重检查锁定是否具有某种固有的优势?
(这个答案只涵盖C#;我不知道Java的内存模型是什么样的。)
主要区别在于潜在的种族。如果你有:
if (f == null)
CompareExchange(ref f, FetchNewValue(), null)
那么 FetchNewValue() 可以在不同线程上任意调用多次。其中一条线程赢得了比赛。如果 FetchNewValue() 非常昂贵,并且您想确保它只被调用一次,那么:
if (f == null)
lock(whatever)
if (f == null)
f = FetchNewValue();
保证 FetchNewValue 仅被调用一次。
如果我个人想要进行低锁延迟初始化,那么我会按照您的建议进行操作:我使用互锁操作并忍受罕见的竞争条件,其中两个线程都运行初始化程序,并且只有一个线程获胜。如果这是不可接受的,那么我使用锁。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)