单例中 getter 和 setter 的线程安全

2024-03-29

我在 Swift 3 中创建了一个简单的单例:

class MySingleton {
    private var myName: String
    private init() {}
    static let shared = MySingleton()

    func setName(_ name: String) {
        myName = name
    }

    func getName() -> String {
        return myName
    }
}

自从我做了init()private ,并且还声明shared实例为static let,我认为初始化器是线程安全的。但是 getter 和 setter 函数呢?myName,它们线程安全吗?


一种稍微不同的方法(来自 Xcode 9 Playground)是使用并发队列而不是串行队列。

final class MySingleton {
    static let shared = MySingleton()

    private let nameQueue = DispatchQueue(label: "name.accessor", qos: .default, attributes: .concurrent)
    private var _name = "Initial name"

    private init() {}

    var name: String {
        get {
            var name = ""
            nameQueue.sync {
                name = _name
            }

            return name
        }
        set {
            nameQueue.async(flags: .barrier) {
                self._name = newValue
            }
        }
    }
}
  • 使用并发队列意味着来自多个线程的多个读取不会互相阻塞。由于获取时没有突变,因此可以同时读取该值,因为......
  • 我们正在使用设置新值.barrier异步调度。该块可以异步执行,因为调用者无需等待值被设置。该块将不会运行,直到它前面的并发队列中的所有其他块都完成为止。因此,当此 setter 等待运行时,现有的挂起读取不会受到影响。屏障意味着当它开始运行时,不会有其他块运行。实际上,在 setter 的持续时间内将队列转变为串行队列。在该块完成之前不能进行进一步的读取。当块完成时,新值已被设置,在此设置器之后添加的任何获取器现在可以同时运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单例中 getter 和 setter 的线程安全 的相关文章

随机推荐

  • 如何使用 CSS 将两个箭头图像(赞成/反对)堆叠在一起?

    向上箭头 gif 和向下箭头 gif So it would look like so 如何创建 3 个 div 并使用 CSS 设计它们的样式 以便这些箭头位于顶部箭头位于底部箭头上方的位置 div class vote div clas
  • Python 脚本给出“:没有这样的文件或目录”

    我有几个 python 脚本 它们工作得很好 但如果我尝试从 bash 运行它 一个脚本 截至今天早上 开始给我这个错误 没有这样的文件或目录 我可以通过执行以下操作来运行 损坏 的脚本python script name py环顾四周后
  • .gitattributes 涂抹和清理过滤器作为存储库的一部分

    我的 git 存储库中有许多模板文件 它们以不同的速率变化 然后使用它们生成 HTML 页面 如果有人报告问题 我希望他们能够告诉我模板文件的哪个版本有问题 目前 我在更改日期时手动将日期输入到文件中 或者 好吧 我尝试这样做 大多数时候我
  • 如何在 Lua 中下载文件,但在运行时写入本地文件

    我正在尝试制作一个更新程序 以便当我的 Lua 应用程序过时时它将使用LuaSocket下载较新的 exe 文件 可以运行我的 Lua 代码 在这个更新程序中 我希望它显示到目前为止已下载的数量 但是 通过以下 HTTP 请求 它会阻止应用
  • 如何以编程方式检查 iOS 上的方向是否已锁定 - Swift

    有没有办法在旋转发生之前以编程方式检查 iPod 方向锁定是否已启用 例如 如果用户要单击按钮 我们是否可以检查方向锁定是否打开 以提醒他们在单击操作发生之前必须关闭方向锁定 目前还没有办法检测方向是否被锁定 您可以只添加应用程序中应支持的
  • 如何将新的键值对添加到现有对象中

    我有一个简单的功能 function pagination opt limit console log opt logs out this gt Object limit 2 layout getConversations if typeo
  • web.xml 中的 cvc-id.3 错误

    在 Eclipse 中为 SpringMVC Web 应用程序编辑 web xml 文件时 我收到此错误消息 cvc id 3 身份字段 约束 web app servlet 名称 唯一性 匹配元素 web app 但是这个 元素没有简单类
  • 确定 Windows 当前是否正在播放声音

    所以我对这个问题思考了一段时间 但我不知道解决这个问题的正确方法是什么 我想使用以下命令确定 Windows 是否在某个时间输出声音Powershell脚本 我可以确定音频驱动程序是否有错误 但我无法确定系统是否正在播放声音 我看了看 NE
  • ruby Date.today 和 DateTime.now 的日期错误

    我已经使用 RVM 安装了 ruby 1 8 6 p383 系统 ruby 是 1 9 1 p378 1 使用 ruby 1 8 时 我从 Date today 和 DateTime now 得到错误的日期 而 Time now 是正确的
  • 从 SVN 获取最后一个文件提交日期

    Subversion 菜鸟 所以请耐心等待 有没有办法从命令行获取文件的最后提交日期 svn info filename
  • Laravel 真的这么慢吗?

    我刚刚开始使用 Laravel 我几乎还没有编写任何代码 但我的页面加载需要将近一秒钟 当我的无框架应用程序和 NodeJS 应用程序花费约 2 毫秒时 这让我有点震惊 拉拉维尔在做什么 这不是正常行为 是吗 是否需要一些微调 Larave
  • 无法使用php在mysql中保存大文本

    query INSERT INTO ARTICLES TITLE BY IN POST VALUES title by in POST post 该代码能够保存小长度文本 但不能保存大文本 的数据类型为POST字段是长文本 另外 如果我通过
  • 使用 C# (telerik) 在 wpf 中自定义弹出窗口的设计

    我在按钮单击事件中显示一个弹出窗口 gt 我在该弹出窗口中保留了一个自定义用户控件 因此每当显示弹出窗口时 都会显示自定义用户控件 但现在我需要修改自定义控件 弹出窗口中当前的自定义控件如下所示 但我需要角落看起来像下面的图片 如何做到这一
  • Angular 4.3 HttpClient:拦截响应

    在有关新的文档中HttpClientModuleAngular 4 3的新版本中 拦截请求的机制解释得非常好 还提到了响应拦截器机制 但我找不到任何相关内容 有谁知道如何拦截响应以便在将正文消息发送到服务之前修改正文消息 Thanks 我最
  • 按关系属性排序 neo4j

    使用 Neo4j 1 9 3 我想创建一个音乐节目列表 在给定的节目中可能会表演三段 每件作品都有一个与之关联的作曲家 并且可能出现在许多不同的程序中 因此我无法在作品节点上放置序列号 我假设我可以创建该程序 其与每个部分的关系如下所示 p
  • Rails 4 加密 Cookie 重放攻击

    我最近升级到 Rails 4 并改用加密 cookie 作为会话存储 不幸的是 这似乎意味着重放攻击是可能的 即如果用户注销 任何 cookie 都不会失效 并且可以用于在没有用户 密码的情况下进行身份验证 据我所知 这是加密 cookie
  • Spring真的不支持接口注入吗?

    我知道 Spring 不支持接口注入 而且我已经读过很多次了 但今天 当我看到 Martin Fowler 写的一篇关于国际奥委会的文章时 link http martinfowler com articles injection html
  • Oracle PIVOT,两次?

    我一直在尝试在 Oracle 11g 中不再使用 DECODE 来透视行 其中有一个方便的 PIVOT 函数 但我可能发现了一个限制 我试图为基表中的每个值返回 2 列 就像是 SELECT somethingId splitId1 spl
  • 将“var”传递给另一个方法

    我可能完全错过了这里的重点 但是 如何将 var 传递给另一个方法 我正在使用 linq 将 XML 加载到可枚举对象列表中 我有不同的对象类型 具有不同的字段 但无论使用哪个对象 我的过程的最后一步都是相同的 XNamespace xml
  • 单例中 getter 和 setter 的线程安全

    我在 Swift 3 中创建了一个简单的单例 class MySingleton private var myName String private init static let shared MySingleton func setNa