拋開語言限制說說什麼是原子性:html
原子性是指一個事物的操做是不可分割的,要麼都發生,要麼都不發生。面試
銀行的轉帳業務就是一個原子性的操做。 張三到銀行給李四轉帳1000元,張三卡里原來有2000元,李四卡里原來也有兩千元,那麼轉帳的步驟應該以下: swift
若是張三的錢扣完,銀行系統癱瘓了,怎麼辦呢?張三的1000塊錢會被會沒呢,固然不會。這時候你的錢會退回來。也就是說銀行的轉帳業務要麼成功張三(1000元)李四(3000元),要麼不發生張三(2000元)李四(2000元)。看看咱們的atomic和nonatomic,咱們一般的理解是線程安全和非線程安全,我以爲這隻在語言層面上描述原子性形成的結果。數組
由於atomic描述的是屬性賦值,屬性賦值中還包含着不少其餘操做,如訪問對象,賦值等等,natomic是保證這個賦值的整個過程的完整性,而且不受其餘線程的干擾,要麼成功要麼失敗。安全
先說個人結論: 用atomic修飾後,這個屬性的setter、getter方法是線程安全的,可是對於整個對象來講不必定是線程安全的。學習
由於在setter和getter賦值取值的時候添加了自旋鎖,不懂看這《oc中的線程鎖》atom
// getter
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
// ...
if (!atomic) return *slot;
// Atomic retain release world
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
id value = objc_retain(*slot);
slotlock.unlock();
// ...
}
// setter
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
// ...
if (!atomic) {
oldValue = *slot;
*slot = newValue;
} else {
spinlock_t& slotlock = PropertyLocks[slot];
slotlock.lock();
oldValue = *slot;
*slot = newValue;
slotlock.unlock();
}
// ...
}
複製代碼
1.對於NSArray類型
@property(atomic)NSArray *array
咱們用atomic修飾,數組的添加和刪除並非線程安全的,這是由於數組比較特殊,咱們要分紅兩部分考慮,一部分是&array也就是這個數組自己,另外一部分是他所指向的內存部分。atomic限制的只是&array部分,對於它指向的對象沒有任何限制。 atomic表示,我TM也很冤啊!!!!spa
2.當線程A進行寫操做,這時其餘線程的讀或者寫操做會由於該操做而等待。當A線程的寫操做結束後,B線程進行寫操做,而後當A線程須要讀操做時,卻得到了在B線程中的值,這就破壞了線程安全,若是有線程C在A線程讀操做前release了該屬性,那麼還會致使程序崩潰。因此僅僅使用atomic並不會使得線程安全,咱們還要爲線程添加lock來確保線程的安全。 我的以爲這個就有點槓精的意味了,atomic還要管到你方法外面去了?????不過面試人家問你還要這麼答,要嚴謹!!,.net
我的理解有問題你們多多提出,討論中才能學習。線程
好文推薦: 《iOS atomic 對象是線程不安全的緣由以及與 nonatomic 的區別》(這個名字很奇怪😄,說白了不安全是由OC對象的引用特性形成的,能夠看下) 《事務四大特徵:原子性,一致性,隔離性和持久性(ACID)》