objective-c - 迈克阿什辛格尔顿 : Placing @synchronized

标签 objective-c cocoa double-checked-locking

我是在 Mike Ash 的“单例的护理和喂养”上看到这个的,他的评论让我有点困惑:

This code is kind of slow, though. Taking a lock is somewhat expensive. Making it more painful is the fact that the vast majority of the time, the lock is pointless. The lock is only needed when foo is nil, which basically only happens once. After the singleton is initialized, the need for the lock is gone, but the lock itself remains.

+(id)sharedFoo {
    static Foo *foo = nil;
    @synchronized([Foo class]) {
        if(!foo) foo = [[self alloc] init];
    }
    return foo;
}

我的问题是,这无疑是一个很好的理由,但为什么你不能写(见下文)将锁限制在 foo 为 nil 的时候?

+(id)sharedFoo {
    static Foo *foo = nil;
    if(!foo) {
        @synchronized([Foo class]) {
            foo = [[self alloc] init];
        }
    }
    return foo;
}

干杯加里

最佳答案

因为测试会受到竞争条件的影响。两个不同的线程可能会独立测试 foo 是否为 nil,然后(顺序地)创建单独的实例。当一个线程执行测试而另一个线程仍在 +[Foo alloc]-[Foo init] 中但尚未设置时,这可能会在您的修改版本中发生foo.

顺便说一句,我根本不会那样做。查看 dispatch_once() 函数,它可以让您保证一个 block 在您的应用程序的生命周期内只执行一次(假设您的目标平台上有 GCD)。

关于objective-c - 迈克阿什辛格尔顿 : Placing @synchronized,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2418780/

相关文章:

iphone - DatePicker 不返回我在编辑 View 中创建它时指定的时间/日期

ios - UITab 栏 - 选择指示器图像 - 更改位置

objective-c - Cocoa 应用程序调用第 3 方 API 崩溃

c++ - 所有用例的双重检查锁是否都已损坏?

java - 带有两个同步块(synchronized block)的 DCL 损坏了?

iphone - 一元表达式的无效参数类型 'void'

iphone - 在具有分发配置文件的设备上运行时应用程序崩溃

cocoa (雪豹)NSTextView的textStorage -setAttributes :range: removes characters!

CoreFoundation 所有权遵循 CreateRule

java - 双重检查锁定的乱序写入