ios 的 atomic/nonatomic ,atomic 不保證線程安全

前言

atomic/nonatomic 是屬性修飾符之一,atomic 代表原子性,nonatomic 代表非原子性;

原子性是防止方法調(diào)用到一半其它操作再次進(jìn)入該方法,導(dǎo)致出現(xiàn)異常情況。

atomic 和 nonatomic 區(qū)別以及實(shí)現(xiàn)

首先我們知道 atomic 代表原子性,nonatomic 代表非原子性;用這兩個(gè)修飾符來修飾屬性,區(qū)別主要在于屬性的 getter/setter 方法:atomic 會(huì)對(duì) setter 方法進(jìn)行加鎖,nonatomic 不會(huì)對(duì) setter 方法加鎖。

atomic 修飾的屬性,在 setter 方法中使用@synchronized加鎖來確保原子操作,但是@synchronized相比于其它類型的鎖,性能是最低效的,因?yàn)槌思渔i之外,額外還會(huì)設(shè)置異常處理機(jī)制,性能消耗較大。這里就是為什么平時(shí)開發(fā)中很少使用 atomic 來修飾屬性。

atomic 與 nonatomic 在 getter/setter 方法區(qū)別如下:

atomic 不保證線程安全

atomic 只會(huì)保證 setter/getter 方法是原子操作的,防止方法調(diào)用到一半其它操作再次進(jìn)入該方法,導(dǎo)致出現(xiàn)異常情況。即原子性保證你訪問的時(shí)候給你返回一個(gè)完好無損的對(duì)象,但是不會(huì)保證線程安全,這里有個(gè)經(jīng)典的例子:

如果線程 A 調(diào)了 getter,與此同時(shí)線程 B 、線程 C 都調(diào)了 setter——那最后線程 A get 到的值,有3種可能:可能是 B、C set之前原始的值,也可能是 B set的值,也可能是 C set的值。同時(shí),最終這個(gè)屬性的值,可能是 B set的值,也有可能是 C set的值。所以atomic可并不能保證對(duì)象的線程安全。

這個(gè)問題其實(shí)包括兩個(gè)塊內(nèi)存,一個(gè)是棧區(qū)指針的內(nèi)存A,一個(gè)是堆區(qū)對(duì)象占用的內(nèi)存B。

atomic 只是對(duì)屬性的 getter/setter 方法加自旋鎖,也就是對(duì)A加鎖,這樣可以保證A是線程安全的。這樣并沒有對(duì)B做任何處理,所以B不是線程安全的。

如果一個(gè)對(duì)象的改變不是直接調(diào)用 getter/setter 方法,而是直接對(duì)對(duì)象內(nèi)部屬性修改、字符串拼接、數(shù)組增加和移除元素等操作,就不能保證這個(gè)對(duì)象是線程安全的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容