在Swift中,当两个线程获取并设置非线程安全属性时会发生什么?

时间:2017-05-19 23:13:28

标签: swift multithreading concurrency thread-safety

以此代码为例:

struct MascotProvider {
    private static var _mascot: MascotType?
    static var mascot: MascotType {
        get {
            if _mascot == nil { _mascot = Mascot() }
            return _mascot!
        }
        set { _mascot = newValue }
    }
}

此代码不是线程安全的,因为如果_mascot为nil且两个线程尝试get mascot,则会实例化Mascot的两个实例。但哪一个会被退回?这是确定性的吗?

此外,当X get之前的线程X set然后线程Y get完成初始化/返回时会发生什么?在这种情况下究竟发生了什么?什么回到X?我确定我曾经看到过去发生bad access错误(我发誓!),但现在无法重现。

有人可以逐步分析正在发生的事情吗?

1 个答案:

答案 0 :(得分:1)

  

但哪一个会被退回?这是确定性的吗?

最后一个分配给_mascot的人。这是不确定的

在get中间出现一组应该没问题。 IIRC,对指针的赋值是原子的,因此它不会像_mascot一样处于旧值和新值的不一致组合中。它可以是完整的旧值,也可以是全新的值(以及它的不确定性)。