在iOS中有幾種方法來解決多線程訪問同一個記憶體位址的互斥同步問題:
方法一,@synchronized(id anObject),(最簡單的方法)
會自動對參數對象加鎖,保證臨界區內的代碼安全執行緒
@synchronized(self){ // 這段代碼對其他 @synchronized(self) 都是互斥的 // self 指向同一個對象}
方法二,NSLock
NSLock對象實現了NSLocking protocol,包含幾個方法:
lock,加鎖
unlock,解鎖
tryLock,嘗試加鎖,如果失敗了,並不會阻塞線程,只是立即返回NO
lockBeforeDate:,在指定的date之前暫時阻塞線程(如果沒有擷取鎖的話),如果到期還沒有擷取鎖,則線程被喚醒,函數立即返回NO
比如:
NSLock *theLock = [[NSLock alloc] init]; if ([theLock lock]) { //do something here [theLock unlock]; }
方法三,NSRecursiveLock,遞迴鎖
NSRecursiveLock,多次調用不會阻塞已擷取該鎖的線程。
NSRecursiveLock *theLock = [[NSRecursiveLock alloc] init]; void MyRecursiveFunction(int value) { [theLock lock]; if (value != 0) { –value; MyRecursiveFunction(value); } [theLock unlock]; } MyRecursiveFunction(5);
方法四,NSConditionLock,條件鎖
NSConditionLock,條件鎖,可以設定條件
//公用部分id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA]; //線程一,生產者 while(true) { [condLock lockWhenCondition:NO_DATA]; //生產資料 [condLock unlockWithCondition:HAS_DATA]; } //線程二,消費者 while (true) { [condLock lockWhenCondition:HAS_DATA]; //消費 [condLock unlockWithCondition:NO_DATA]; }
方法五,NSDistributedLock,分布鎖
NSDistributedLock,分布鎖,檔案方式實現,可以跨進程
用tryLock方法擷取鎖。
用unlock方法釋放鎖。
如果一個擷取鎖的進程在釋放鎖之前掛了,那麼鎖就一直得不到釋放了,此時可以通過breakLock強行擷取鎖。