atomic和线程安全的理解
线程安全
如果多线程下,一直操作i = i + 1
,可能出现线程不安全
i = i + 1
这个表达式涉及三步,取值,修改,赋值;
例如i = 1
,线程A这时候进行i = i + 1
,先取值,在修改(i+1)的过程中,这时候线程B进来了,他也要执行i = i + 1
,他也先取值i,这时候i还是等于1
线程A执行完,i=2,
线程B执行完,i=2
我们是执行了两次i = i + 1
如果线程安全的话,这时候i应该等于3
那么我们要怎么改成线程安全呢,就是对操作加锁i = i + 1
这样当线程A执行i = i + 1
这个代码的时候,因为被加锁了,线程B只能等待,直到线程A执行完
atomic为啥线程不安全
atomic
是set
和get
方法内加锁,其实他跟线程安全都不搭边
如果要举个例子的话,刚才i = i + 1
这个例子,就算是atomic
修饰i属性,那么也是线程不安全的
以前我对线程安全概念一直懵了,一直纠结
无论怎么加锁
线程A 读
线程B 写
线程C 读
线程D 写
好像对读写加锁,都没法解决最后数据不对的问题
后来才明白,如果我们将一个操作,比如读写一起加锁,那么就线程安全了
很难描述这个情况,不知道大家有没有get到我的点,大概意思就是atomic
是读写方法加锁,但是真的要做到线程安全,应该是这一系列的操作加锁
看完这个文章iOS多线程到底不安全在哪里?的一些补充,记录
原子性:
原子性能保证代码串行的执行,能保证代码执行到一半的时候,不会有另一个线程介入。
原子性是个相对的概念,它所针对的对象,粒度可大可小。
线程安全
多线程访问时出现意料之外的结果
内存访问
在文章中说到,内存的访问是串行的,当我看到这个的时候,我就想,是串行的,那么怎么还有多线程安全问题。
其实问题在于,原子性和线程安全的理解,在我们的代码中,想要线程安全,应该是一系列的操作是原子性的,例如i = i + 1
这个操作是原子性的,那么去内存中读数据,写数据的顺序不会被其他线程的操作插入,导致出现意料之外的结果
如何用Xcode8解决多线程问题
其中讲了四个多线程不安全的场景,em。。。。还不错可以记着