from http://mrpeak.cn/blog/ios-thread-safety/

Atomic property does not Thread-safe

是不是使用了atomic就一定多线程安全呢?我们可以看看如下代码:

@property(atomic,assign)int intA;
//thread A
for (int i = 0; i < 10000; i++) {
    self.intA = self.intA + 1;
    NSLog(@"Thread A: %d\n",self.intA);
}
//thread B
for (int i=0; i < 10000; i++) {
    self.intA = self.intA + 1;
    NSLog(@"Thread B: %d\n",self.intA);
}

即使我将intA声明为atomic,最后的结果也不一定会是20000。原因就是因为self.intA = self.intA + 1;不是原子操作,虽然intA的getter和setter是原子操作,但当我们使用intA的时候,整个语句并不是原子的,这行赋值的代码至少包含读取(load),+1(add),赋值(store)三步操作,当前线程store的时候可能其他线程已经执行了若干次store了,导致最后的值小于预期值。这种场景我们也可以称之为多线程不安全

Property多线程安全小结:

简而言之,atomic的作用只是给getter和setter加了个锁,atomic只能保证代码进入getter或者setter函数内部时是安全的,一旦出了getter和setter,多线程安全只能靠程序员自己保障了。所以atomic属性和使用property的多线程安全并没什么直接的联系。另外,atomic由于加锁也会带来一些性能损耗,所以我们在编写iOS代码的时候,一般声明property为nonatomic,在需要做多线程安全的场景,自己去额外加锁做同步。

Add mutex lock For objc,

- (void)myMethod:(id)anObj {
    @synchronized(anObj) {
        // 在括号内 anObj 不会被其他线程改变
    }

}

Add mutex lock For swift,

// How to declare
func synchronized(_ lock: AnyObject, closure: () -> ()) {

objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}

// When using
func myMethodLocked(anObj: AnyObject!) {
    synchronized(anObj) {
    // 在括号内 anObj 不会被其他线程改变
    }

}

results matching ""

    No results matching ""