Tag: 原子

并发队列中的原子属性

关于原子如何工作的研究~~~ 从我关于引用计数的文章中,我对原子的工作原理以及它不是线程安全的方法很感兴趣。 因此,本文致力于并发操作中有关原子属性的一些示例代码。 并发队列可以包含多个任务,但是任务的顺序由操作系统管理,这将在后面显示。 根据Apple官方网站,我们可以创建三种主要的Dispatch Queue类型: 并发队列可以很容易地创建如下: 现在,我将创建一个将在队列上运行的函数: 为了在队列上运行testRunner ,您需要通过dispatch_async调用它们: 由于testRunner只循环一次,因此OS可以轻松地连续照顾它们,显示NS​​Logs: 但是,如果将循环增加到5,则它们将不会连续运行: 为了证明它们是不同的线程,只需在调用该函数的行上放置一个断点,然后您可以检查正在运行的线程: 由于操作是由CPU管理的,因此可能有机会在同一线程上进行操作。 但是,当线程大得多(i <500)时,看起来它们有更大的机会在不同的线程上进行操作。 [我仍然需要阅读更多有关此内容的信息,但是如果您有任何想补充的内容,请给我一个共同的名字,一千个感谢^^] 原子属性怎么样? 在这里,我创建了一个名为AtomicModel的类,该类包含两个属性: atomicString和nonAtomicString 在功能runAtomicThreads中 ,创建并发调度,并创建两个线程,一个线程调用[self atomicSetter],另一个调用[self atomicGetter]。 基本上, atomicSetter的计数从0到100000,并将atomicString设置为偶数为“很长的字符串”,而奇数为“ string”。 尽管atomicGetter可以做同样的事情,但是当atomicString.length≥10时,它将创建一个subStr 。 如果您运行该代码,则当for循环重复一个较小的数字时,您将看到没有错误。 但是,当重复计数增加时,您将有机会反弹到错误: 那么到底发生了什么呢? 为了帮助我理解发生了什么,我在线程B中获取subStr之前和之后都记录了atomicString 。 从线程B打印出的最后一句话看,线程B似乎认为atomicString ==“一个很长的字符串” 让我们看看线程A对此有何看法。 显然,线程A和线程B在atomicString应该是什么值上存在分歧。 因此,当线程B认为atomicString .length≥10时 ,线程A将其更改为长度小于10的“字符串”。 这导致代码崩溃。 结果,这证明原子属性不是线程安全的。 当使用非原子属性时,也会发生相同的错误,唯一的区别是非原子比原子快得多。