什么時(shí)候需要用到同步
在同一塊內(nèi)存谨敛,可能會(huì)被多個(gè)線程并發(fā)訪問(wèn)的情況下跨嘉,一般考慮數(shù)據(jù)同步
同步機(jī)制分為3種
根據(jù)不同的同步機(jī)制尊蚁,大致可以分3種亡笑,分別是:
1、鎖:阻塞當(dāng)前線程枝誊,等待一定條件况芒,再往下走
2、串行隊(duì)列:通過(guò)隊(duì)列叶撒,把不同的數(shù)據(jù)操作代碼绝骚,放在同一個(gè)線程執(zhí)行
3、信號(hào)量:控制線程掛起/喚醒
下面分別來(lái)說(shuō)說(shuō)它們各自的工作原理祠够。
鎖
以自旋鎖為例:
線程1走在lock與unlock之間時(shí)压汪,
線程2走到lock時(shí),會(huì)執(zhí)行原地進(jìn)行循環(huán)古瓤,轉(zhuǎn)圈止剖,并阻止代碼往下走。
這樣落君,線程2和1不會(huì)同時(shí)訪問(wèn)到同一片資源穿香。等線程1訪問(wèn)完了,線程2就會(huì)跳出循環(huán)绎速,再進(jìn)行數(shù)據(jù)操作皮获。
串行隊(duì)列
不同的線程,把各自數(shù)據(jù)操作任務(wù)纹冤,都放入隊(duì)列中洒宝。然后,隊(duì)列依次把任務(wù)取出來(lái)萌京,放到同一條線程中執(zhí)行雁歌,實(shí)現(xiàn)同步
信號(hào)量
原理跟自旋類(lèi)似。只不過(guò)是從循環(huán)變成線程掛起知残。
如果把它們兩個(gè)比喻成過(guò)紅綠燈的車(chē)子靠瞎,自旋就是紅燈時(shí)原地打圈,信號(hào)量就是紅燈停車(chē),等綠燈再通過(guò)较坛。
兩者相比印蔗,
自旋:一個(gè)不停運(yùn)行的循環(huán)扒最,消耗cpu計(jì)算資源丑勤,不需要喚醒,響應(yīng)快
信號(hào)量:掛起與喚醒有時(shí)間開(kāi)銷(xiāo)吧趣,響應(yīng)稍慢法竞,但掛起節(jié)省cpu
iOS中的同步
上鎖
簡(jiǎn)單的有NSLock,@synchronized()使用串行隊(duì)列
dispatch_queue强挫,dispatch代碼塊到同一個(gè)串行queue使用信號(hào)量
dispatch_semaphore岔霸,通過(guò)wait與signal控制
或者dispatch_group,同理俯渤。
最后說(shuō)兩句
一般的業(yè)務(wù)場(chǎng)景呆细,客戶(hù)端沒(méi)有什么大并發(fā),通常瓶頸不在于用什么鎖八匠,@synchronized()充以滿(mǎn)足業(yè)務(wù)需求絮爷。
只有一點(diǎn)值得注意的是,@synchronized(一塊地址)梨树,一地址對(duì)應(yīng)一個(gè)鎖坑夯。
常說(shuō)@synchronized()性能差,很多時(shí)候是使用不規(guī)范抡四。濫用@synchronized(self)柜蜈,相當(dāng)于所有業(yè)務(wù)都使用的同一個(gè)鎖。這意味著在有些時(shí)候業(yè)務(wù)A的進(jìn)度指巡,需要等待不相關(guān)的業(yè)務(wù)B淑履,能不卡么。
正確的使用姿勢(shì)是:合理地使用@synchronized( lock_obj1 / lock_obj2 ... )藻雪,不同業(yè)務(wù)使用不同的LockObject秘噪。