【问题标题】:The purpose of having a synchronising thread拥有同步线程的目的
【发布时间】:2018-11-12 06:18:51
【问题描述】:

下面的代码应该设置一个线程安全的单例:

class Singleton {
    static var shared = Singleton()
    private let internalQueue = DispatchQueue(label: "SingletionInternalQueue", qos: .default, attributes: .concurrent)

    private var _foo: String = "aaa"

    var foo: String {
        get {
            return internalQueue.sync { _foo }
        }
        set (newState) {
            internalQueue.async(flags: .barrier) { self._foo = newState }
        }
    }

    func setup(string: String) {
        foo = string
    }
}

来源:Thread safe singleton in swift

但我不明白这样做的目的。

例如,如果我想get foo 的值,我不应该只能读取它吗?操作应该总是在主线程上执行,那么添加另一个线程有什么意义呢?

与set类似:如果我担心多个源同时设置值,我们不能简化代码并消除.barrier参数吗?

internalQueue.async(flags: .barrier) { self._foo = newState}

如果它在sync 块中,这不会强制它进入主线程吗?如果是这样,那为什么代码不只需要self._foo = newState?

【问题讨论】:

  • “由于获取 foo 值将始终在主队列中执行” - 如果您只使用主队列中的此单例,则无需任何同步。关键是要确保在多个不同线程上同时使用单例是安全的。
  • 我想知道您的问题是否被误读。当声明 “由于获取 foo 值将始终在主队列中执行” 时,您是在声明(1)您只会这样做还是(2)所有此类获取仅在主队列中发生语言设计?

标签: ios swift thread-safety singleton


【解决方案1】:

你是对的:只要你只从主线程访问单例,就不需要同步。在这种情况下,我更愿意通过使用如下代码来明确要求:

assert(Thread.isMainThread)

这将在生产版本中进行优化,但会确保您在调试模式下发现无意的编程错误(例如,当您从 URLSession 完成处理程序调用代码时)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 2014-04-30
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多