iOS中的各種鎖

在日常開(kāi)發(fā)過(guò)程中匿刮,為了提升程序運(yùn)行效率,以及用戶體驗(yàn)探颈,我們經(jīng)常使用多線程熟丸。在使用多線程的過(guò)程中,難免會(huì)遇到資源競(jìng)爭(zhēng)問(wèn)題伪节。我們采用鎖的機(jī)制來(lái)確保線程安全光羞。

線程安全

當(dāng)一個(gè)線程訪問(wèn)數(shù)據(jù)的時(shí)候,其他的線程不能對(duì)其進(jìn)行訪問(wèn)怀大,直到該線程訪問(wèn)完畢纱兑。即,同一時(shí)刻化借,對(duì)同一個(gè)數(shù)據(jù)操作的線程只有一個(gè)潜慎。只有確保了這樣,才能使數(shù)據(jù)不會(huì)被其他線程污染蓖康。而線程不安全铐炫,則是在同一時(shí)刻可以有多個(gè)線程對(duì)該數(shù)據(jù)進(jìn)行訪問(wèn),從而得不到預(yù)期的結(jié)果蒜焊。

比如寫(xiě)文件和讀文件倒信,當(dāng)一個(gè)線程在寫(xiě)文件的時(shí)候,理論上來(lái)說(shuō)泳梆,如果這個(gè)時(shí)候另一個(gè)線程來(lái)直接讀取的話鳖悠,那么得到將是不可預(yù)期的結(jié)果。

為了線程安全优妙,我們可以使用鎖的機(jī)制來(lái)確保乘综,同一時(shí)刻只有同一個(gè)線程來(lái)對(duì)同一個(gè)數(shù)據(jù)源進(jìn)行訪問(wèn)。在開(kāi)發(fā)過(guò)程中我們通常使用以下幾種鎖套硼。

  1. NSLock
  2. NSRecursiveLock
  3. NSCondition
  4. NSConditionLock
  5. pthread_mutex
  6. pthread_rwlock
  7. POSIX Conditions
  8. OSSpinLock
  9. os_unfair_lock
  10. dispatch_semaphore
  11. @synchronized

信號(hào)量

在多線程環(huán)境下用來(lái)確保代碼不會(huì)被并發(fā)調(diào)用卡辰。在進(jìn)入一段代碼前,必須獲得一個(gè)信號(hào)量熟菲,在結(jié)束代碼前看政,必須釋放該信號(hào)量,其他想要想要執(zhí)行該代碼的線程必須等待直到前者釋放了該信號(hào)量抄罕。

以一個(gè)停車(chē)場(chǎng)的運(yùn)作為例。簡(jiǎn)單起見(jiàn)于颖,假設(shè)停車(chē)場(chǎng)只有三個(gè)車(chē)位呆贿,一開(kāi)始三個(gè)車(chē)位都是空的。這時(shí)如果同時(shí)來(lái)了五輛車(chē),看門(mén)人允許其中三輛直接進(jìn)入做入,然后放下車(chē)攔冒晰,剩下的車(chē)則必須在入口等待,此后來(lái)的車(chē)也都不得不在入口處等待竟块。這時(shí)壶运,有一輛車(chē)離開(kāi)停車(chē)場(chǎng),看門(mén)人得知后浪秘,打開(kāi)車(chē)攔蒋情,放入外面的一輛進(jìn)去,如果又離開(kāi)兩輛耸携,則又可以放入兩輛棵癣,如此往復(fù)。
在這個(gè)停車(chē)場(chǎng)系統(tǒng)中夺衍,車(chē)位是公共資源狈谊,每輛車(chē)好比一個(gè)線程,看門(mén)人起的就是信號(hào)量的作用沟沙。

互斥鎖

一種用來(lái)防止多個(gè)線程同一時(shí)刻對(duì)共享資源進(jìn)行訪問(wèn)的信號(hào)量河劝,它的原子性確保了如果一個(gè)線程鎖定了一個(gè)互斥量,將沒(méi)有其他線程在同一時(shí)間可以鎖定這個(gè)互斥量矛紫。它的唯一性確保了只有它解鎖了這個(gè)互斥量丧裁,其他線程才可以對(duì)其進(jìn)行鎖定。當(dāng)一個(gè)線程鎖定一個(gè)資源的時(shí)候含衔,其他對(duì)該資源進(jìn)行訪問(wèn)的線程將會(huì)被掛起煎娇,直到該線程解鎖了互斥量,其他線程才會(huì)被喚醒贪染,進(jìn)一步才能鎖定該資源進(jìn)行操作缓呛。

NSLock

NSLock實(shí)現(xiàn)了最基本的互斥鎖,遵循了 NSLocking 協(xié)議杭隙,通過(guò) lockunlock 來(lái)進(jìn)行鎖定和解鎖哟绊。其使用也非常簡(jiǎn)單

- (void)doSomething {
   [self.lock lock];
   //TODO: do your stuff
   [self.lock unlock];
}

由于是互斥鎖,當(dāng)一個(gè)線程進(jìn)行訪問(wèn)的時(shí)候痰憎,該線程獲得鎖票髓,其他線程進(jìn)行訪問(wèn)的時(shí)候,將被操作系統(tǒng)掛起铣耘,直到該線程釋放鎖洽沟,其他線程才能對(duì)其進(jìn)行訪問(wèn),從而卻確保了線程安全蜗细。但是如果連續(xù)鎖定兩次裆操,則會(huì)造成死鎖問(wèn)題怒详。那如果想在遞歸中使用鎖,那要怎么辦呢踪区,這就用到了 NSRecursiveLock 遞歸鎖昆烁。

NSRecursiveLock

遞歸鎖,顧名思義缎岗,可以被一個(gè)線程多次獲得静尼,而不會(huì)引起死鎖。它記錄了成功獲得鎖的次數(shù)传泊,每一次成功的獲得鎖鼠渺,必須有一個(gè)配套的釋放鎖和其對(duì)應(yīng),這樣才不會(huì)引起死鎖或渤。只有當(dāng)所有的鎖被釋放之后系冗,其他線程才可以獲得鎖

NSRecursiveLock *theLock = [[NSRecursiveLock alloc] init];
 
void MyRecursiveFunction(int value)
{
    [theLock lock];
    if (value != 0)
    {
        --value;
        MyRecursiveFunction(value);
    }
    [theLock unlock];
}
 
MyRecursiveFunction(5);

NSCondition

NSCondition 是一種特殊類(lèi)型的鎖,通過(guò)它可以實(shí)現(xiàn)不同線程的調(diào)度薪鹦。一個(gè)線程被某一個(gè)條件所阻塞掌敬,直到另一個(gè)線程滿足該條件從而發(fā)送信號(hào)給該線程使得該線程可以正確的執(zhí)行。比如說(shuō)池磁,你可以開(kāi)啟一個(gè)線程下載圖片奔害,一個(gè)線程處理圖片。這樣的話地熄,需要處理圖片的線程由于沒(méi)有圖片會(huì)阻塞华临,當(dāng)下載線程下載完成之后,則滿足了需要處理圖片的線程的需求端考,這樣可以給定一個(gè)信號(hào)雅潭,讓處理圖片的線程恢復(fù)運(yùn)行。

- (void)download {
    [self.condition lock];
    //TODO: 下載文件代碼
    if (donloadFinish) { // 下載結(jié)束后却特,給另一個(gè)線程發(fā)送信號(hào)扶供,喚起另一個(gè)處理程序
        [self.condition signal];
        [self.condition unlock];
    }
}

- (void)doStuffWithDownloadPicture {
    [self.condition lock];
    
    while (!donloadFinish) {
        [self.condition wait];
    }
    //TODO: 處理圖片代碼
    
    [self.condition unlock];
}

NSConditionLock

NSConditionLock 對(duì)象所定義的互斥鎖可以在使得在某個(gè)條件下進(jìn)行鎖定和解鎖。它和 NSCondition 很像裂明,但實(shí)現(xiàn)方式是不同的椿浓。

當(dāng)兩個(gè)線程需要特定順序執(zhí)行的時(shí)候,例如生產(chǎn)者消費(fèi)者模型闽晦,則可以使用 NSConditionLock 扳碍。當(dāng)生產(chǎn)者執(zhí)行執(zhí)行的時(shí)候,消費(fèi)者可以通過(guò)特定的條件獲得鎖仙蛉,當(dāng)生產(chǎn)者完成執(zhí)行的時(shí)候笋敞,它將解鎖該鎖,然后把鎖的條件設(shè)置成喚醒消費(fèi)者線程的條件捅儒。鎖定和解鎖的調(diào)用可以隨意組合液样,lockunlockWithCondition: 配合使用 lockWhenCondition:unlock 配合使用振亮。

- (void)producer {
    while (YES) {
        [self.conditionLock lock];
        NSLog(@"have something");
        self.count++;
        [self.conditionLock unlockWithCondition:1];
    }
}

- (void)consumer {
    while (YES) {
        [self.conditionLock lockWhenCondition:1];
        NSLog(@"use something");
        self.count--;
        [self.conditionLock unlockWithCondition:0];
    }
}

當(dāng)生產(chǎn)者釋放鎖的時(shí)候巧还,把條件設(shè)置成了1鞭莽。這樣消費(fèi)者可以獲得該鎖,進(jìn)而執(zhí)行程序麸祷,如果消費(fèi)者獲得鎖的條件和生產(chǎn)者釋放鎖時(shí)給定的條件不一致澎怒,則消費(fèi)者永遠(yuǎn)無(wú)法獲得鎖,也不能執(zhí)行程序阶牍。同樣喷面,如果消費(fèi)者釋放鎖給定的條件和生產(chǎn)者獲得鎖給定的條件不一致的話,則生產(chǎn)者也無(wú)法獲得鎖走孽,程序也不能執(zhí)行惧辈。

pthread_mutex

POSIX 互斥鎖是一種超級(jí)易用的互斥鎖,使用的時(shí)候磕瓷,只需要初始化一個(gè) pthread_mutex_tpthread_mutex_lock 來(lái)鎖定 pthread_mutex_unlock 來(lái)解鎖盒齿,當(dāng)使用完成后,記得調(diào)用 pthread_mutex_destroy 來(lái)銷(xiāo)毀鎖困食。

    pthread_mutex_init(&lock,NULL);
    pthread_mutex_lock(&lock);
    //do your stuff
    pthread_mutex_unlock(&lock);
    pthread_mutex_destroy(&lock);

pthread_rwlock

讀寫(xiě)鎖边翁,在對(duì)文件進(jìn)行操作的時(shí)候,寫(xiě)操作是排他的硕盹,一旦有多個(gè)線程對(duì)同一個(gè)文件進(jìn)行寫(xiě)操作符匾,后果不可估量,但讀是可以的瘩例,多個(gè)線程讀取時(shí)沒(méi)有問(wèn)題的啊胶。

  • 當(dāng)讀寫(xiě)鎖被一個(gè)線程以讀模式占用的時(shí)候,寫(xiě)操作的其他線程會(huì)被阻塞垛贤,讀操作的其他線程還可以繼續(xù)進(jìn)行焰坪。
  • 當(dāng)讀寫(xiě)鎖被一個(gè)線程以寫(xiě)模式占用的時(shí)候,寫(xiě)操作的其他線程會(huì)被阻塞南吮,讀操作的其他線程也被阻塞琳彩。
// 初始化
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER
// 讀模式
pthread_rwlock_wrlock(&lock);
// 寫(xiě)模式
pthread_rwlock_rdlock(&lock);
// 讀模式或者寫(xiě)模式的解鎖
pthread_rwlock_unlock(&lock);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        [self readBookWithTag:1];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        [self readBookWithTag:2];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        [self writeBook:3];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        [self writeBook:4];
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        [self readBookWithTag:5];
    });


- (void)readBookWithTag:(NSInteger )tag {
    pthread_rwlock_rdlock(&rwLock);
    NSLog(@"start read ---- %ld",tag);
    self.path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@".doc"];
    self.contentString = [NSString stringWithContentsOfFile:self.path encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"end   read ---- %ld",tag);
    pthread_rwlock_unlock(&rwLock);
}

- (void)writeBook:(NSInteger)tag {
    pthread_rwlock_wrlock(&rwLock);
    NSLog(@"start wirte ---- %ld",tag);
    [self.contentString writeToFile:self.path atomically:YES encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"end   wirte ---- %ld",tag);
    pthread_rwlock_unlock(&rwLock);
}
start   read ---- 1
start   read ---- 2
end    read ---- 1
end    read ---- 2
start   wirte ---- 3
end    wirte ---- 3
start   wirte ---- 4
end    wirte ---- 4
start   read ---- 5
end    read ---- 5

POSIX Conditions

POSIX 條件鎖需要互斥鎖和條件兩項(xiàng)來(lái)實(shí)現(xiàn),雖然看起來(lái)沒(méi)什么關(guān)系部凑,但在運(yùn)行時(shí)中露乏,互斥鎖將會(huì)與條件結(jié)合起來(lái)。線程將被一個(gè)互斥和條件結(jié)合的信號(hào)來(lái)喚醒涂邀。

首先初始化條件和互斥鎖瘟仿,當(dāng) ready_to_goflase 的時(shí)候,進(jìn)入循環(huán)比勉,然后線程將會(huì)被掛起劳较,直到另一個(gè)線程將 ready_to_go 設(shè)置為 true 的時(shí)候驹止,并且發(fā)送信號(hào)的時(shí)候,該線程會(huì)才被喚醒观蜗。

pthread_mutex_t mutex;
pthread_cond_t condition;
Boolean     ready_to_go = true;
 
void MyCondInitFunction()
{
    pthread_mutex_init(&mutex);
    pthread_cond_init(&condition, NULL);
}
 
void MyWaitOnConditionFunction()
{
    // Lock the mutex.
    pthread_mutex_lock(&mutex);
 
    // If the predicate is already set, then the while loop is bypassed;
    // otherwise, the thread sleeps until the predicate is set.
    while(ready_to_go == false)
    {
        pthread_cond_wait(&condition, &mutex);
    }
 
    // Do work. (The mutex should stay locked.)
 
    // Reset the predicate and release the mutex.
    ready_to_go = false;
    pthread_mutex_unlock(&mutex);
}

void SignalThreadUsingCondition()
{
    // At this point, there should be work for the other thread to do.
    pthread_mutex_lock(&mutex);
    ready_to_go = true;
 
    // Signal the other thread to begin work.
    pthread_cond_signal(&condition);
 
    pthread_mutex_unlock(&mutex);
}

OSSpinLock

自旋鎖臊恋,和互斥鎖類(lèi)似,都是為了保證線程安全的鎖墓捻。但二者的區(qū)別是不一樣的抖仅,對(duì)于互斥鎖,當(dāng)一個(gè)線程獲得這個(gè)鎖之后砖第,其他想要獲得此鎖的線程將會(huì)被阻塞撤卢,直到該鎖被釋放。但自選鎖不一樣梧兼,當(dāng)一個(gè)線程獲得鎖之后放吩,其他線程將會(huì)一直循環(huán)在哪里查看是否該鎖被釋放。所以羽杰,此鎖比較適用于鎖的持有者保存時(shí)間較短的情況下渡紫。

// 初始化
spinLock = OS_SPINLOCK_INIT;
// 加鎖
OSSpinLockLock(&spinLock);
// 解鎖
OSSpinLockUnlock(&spinLock);

然而,YYKit 作者 @ibireme 的文章也有說(shuō)這個(gè)自旋鎖存在優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題忽洛,具體文章可以戳 不再安全的 OSSpinLock腻惠。

os_unfair_lock

自旋鎖已經(jīng)不在安全,然后蘋(píng)果又整出來(lái)個(gè) os_unfair_lock_t (╯‵□′)╯︵┻━┻
這個(gè)鎖解決了優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題欲虚。

    os_unfair_lock_t unfairLock;
    unfairLock = &(OS_UNFAIR_LOCK_INIT);
    os_unfair_lock_lock(unfairLock);
    os_unfair_lock_unlock(unfairLock);

dispatch_semaphore

信號(hào)量機(jī)制實(shí)現(xiàn)鎖集灌,等待信號(hào),和發(fā)送信號(hào)复哆,正如前邊所說(shuō)的看門(mén)人一樣欣喧,當(dāng)有多個(gè)線程進(jìn)行訪問(wèn)的時(shí)候,只要有一個(gè)獲得了信號(hào)梯找,其他線程的就必須等待該信號(hào)釋放唆阿。

- (void)semphone:(NSInteger)tag {
    
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW);
    // do your stuff
    dispatch_semaphore_signal(semaphore);
}

@synchronized

一個(gè)便捷的創(chuàng)建互斥鎖的方式,它做了其他互斥鎖所做的所有的事情锈锤。

- (void)myMethod:(id)anObj
{
    @synchronized(anObj)
    {
        // Everything between the braces is protected by the @synchronized directive.
    }
}

如果你在不同的線程中傳過(guò)去的是一樣的標(biāo)識(shí)符驯鳖,先獲得鎖的會(huì)鎖定代碼塊,另一個(gè)線程將被阻塞久免,如果傳遞的是不同的標(biāo)識(shí)符浅辙,則不會(huì)造成線程阻塞。

總結(jié)

應(yīng)當(dāng)針對(duì)不同的操作使用不同的鎖阎姥,而不能一概而論那種鎖的加鎖解鎖速度快记舆。

  • 當(dāng)進(jìn)行文件讀寫(xiě)的時(shí)候,使用 pthread_rwlock 較好呼巴,文件讀寫(xiě)通常會(huì)消耗大量資源泽腮,而使用互斥鎖同時(shí)讀文件的時(shí)候會(huì)阻塞其他讀文件線程御蒲,而 pthread_rwlock 不會(huì)。
  • 當(dāng)性能要求較高時(shí)候诊赊,可以使用 pthread_mutex 或者 dispath_semaphore厚满,由于 OSSpinLock 不能很好的保證線程安全,而在只有在 iOS10 中才有 os_unfair_lock 豪筝,所以痰滋,前兩個(gè)是比較好的選擇摘能。既可以保證速度续崖,又可以保證線程安全。
  • 對(duì)于 NSLock 及其子類(lèi)团搞,速度來(lái)說(shuō) NSLock < NSCondition < NSRecursiveLock < NSConditionLock 严望。

引用
1.Threading Programming Guide
2.百度百科-線程安全
3.百度百科-信號(hào)量
4.百度百科-互斥鎖
5.不再安全的 OSSpinLock

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逻恐,隨后出現(xiàn)的幾起案子像吻,更是在濱河造成了極大的恐慌,老刑警劉巖复隆,帶你破解...
    沈念sama閱讀 222,946評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拨匆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡挽拂,警方通過(guò)查閱死者的電腦和手機(jī)惭每,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)亏栈,“玉大人台腥,你說(shuō)我怎么就攤上這事∪薇保” “怎么了黎侈?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,716評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)闷游。 經(jīng)常有香客問(wèn)我峻汉,道長(zhǎng),這世上最難降的妖魔是什么脐往? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,222評(píng)論 1 300
  • 正文 為了忘掉前任休吠,我火速辦了婚禮,結(jié)果婚禮上钙勃,老公的妹妹穿的比我還像新娘蛛碌。我一直安慰自己,他們只是感情好辖源,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布蔚携。 她就那樣靜靜地躺著希太,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酝蜒。 梳的紋絲不亂的頭發(fā)上誊辉,一...
    開(kāi)封第一講書(shū)人閱讀 52,807評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音亡脑,去河邊找鬼堕澄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛霉咨,可吹牛的內(nèi)容都是我干的蛙紫。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼途戒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坑傅!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起喷斋,我...
    開(kāi)封第一講書(shū)人閱讀 40,189評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤唁毒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后星爪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體浆西,經(jīng)...
    沈念sama閱讀 46,712評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評(píng)論 3 343
  • 正文 我和宋清朗相戀三年顽腾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了近零。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,926評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡崔泵,死狀恐怖秒赤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情憎瘸,我是刑警寧澤入篮,帶...
    沈念sama閱讀 36,580評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站幌甘,受9級(jí)特大地震影響潮售,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锅风,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評(píng)論 3 336
  • 文/蒙蒙 一酥诽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧皱埠,春花似錦肮帐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,750評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)托修。三九已至,卻和暖如春恒界,著一層夾襖步出監(jiān)牢的瞬間睦刃,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,867評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工十酣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涩拙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,368評(píng)論 3 379
  • 正文 我出身青樓耸采,卻偏偏與公主長(zhǎng)得像兴泥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子洋幻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 在日常開(kāi)發(fā)過(guò)程中郁轻,為了提升程序運(yùn)行效率,以及用戶體驗(yàn)文留,我們經(jīng)常使用多線程。在使用多線程的過(guò)程中竭沫,難免會(huì)遇到資源競(jìng)爭(zhēng)...
    星捷閱讀 841評(píng)論 0 0
  • 在日常開(kāi)發(fā)過(guò)程中燥翅,為了提升程序運(yùn)行效率,以及用戶體驗(yàn)蜕提,我們經(jīng)常使用多線程森书。在使用多線程的過(guò)程中,難免會(huì)遇到資源競(jìng)爭(zhēng)...
    知識(shí)小集閱讀 5,728評(píng)論 8 61
  • 鎖是一種同步機(jī)制谎势,用于多線程環(huán)境中對(duì)資源訪問(wèn)的限制iOS中常見(jiàn)鎖的性能對(duì)比圖(摘自:ibireme): iOS鎖的...
    LiLS閱讀 1,524評(píng)論 0 6
  • 引用自多線程編程指南應(yīng)用程序里面多個(gè)線程的存在引發(fā)了多個(gè)執(zhí)行線程安全訪問(wèn)資源的潛在問(wèn)題凛膏。兩個(gè)線程同時(shí)修改同一資源有...
    Mitchell閱讀 2,001評(píng)論 1 7
  • 今天中午參加了CS Dept舉辦的Career Strategy類(lèi)的小講座,講座的主題是關(guān)于個(gè)人理財(cái)Persona...
    可妞兒閱讀 1,143評(píng)論 1 0