iOS各種鎖簡(jiǎn)介(上)

iOS各種鎖簡(jiǎn)介(上)

本篇文章主要介紹iOS中幾種不同的鎖的實(shí)現(xiàn)方式,既然是簡(jiǎn)介,這里不會(huì)涉及到原理上面的東西,主要還是如何使用。

在開始之前,我們先構(gòu)建一個(gè)測(cè)試類,假設(shè)這個(gè)類是一個(gè)共享資源,提供兩個(gè)方法method1和method2,假設(shè)method1和method2是互斥的,代碼如下:

@implementation TestObject

- (void)method1 {
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

- (void)method2 {
    NSLog(@"%@",NSStringFromSelector(_cmd));
}

@end

NSLock

NSLock是cocoa提供給我們最基本的鎖對(duì)象,這個(gè)是最簡(jiǎn)單的一個(gè)鎖,NSLock提供了lock和unlock兩個(gè)方法,分別是加鎖和解鎖。NSLock內(nèi)部實(shí)際是封裝了pthread_mutex。使用方法很簡(jiǎn)單,代碼如下:

- (void)lockDemo {
    TestObject *obj = [[TestObject alloc] init];
    NSLock *lock = [[NSLock alloc] init];

    // 線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [lock lock];
        [obj method1];
        sleep(10);
        [lock unlock];
    });

    // 線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        [lock lock];
        [obj method2];
        [lock unlock];
    });
}

從打印結(jié)果可以看出,線程1獲得鎖之后,線程2會(huì)一直等待,直到線程1釋放鎖(unlock)之后才會(huì)執(zhí)行。

@synchronized

@synchronized的使用方式很簡(jiǎn)單,先看代碼:

- (void)synchronizedDemo {
    TestObject *obj = [[TestObject alloc] init];

    // 線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        @synchronized(obj) {
            [obj method1];
            sleep(10);
        }
    });

    // 線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        @synchronized(obj) {
            [obj method2];
        }
    });
}

跟NSLock加鎖的結(jié)果一樣,線程2也是等到線程1釋放鎖之后才執(zhí)行。從代碼中可以看出,@synchronized實(shí)現(xiàn)鎖非常方便,注意:@synchronized指令中使用的obj為鎖的唯一標(biāo)識(shí),只有標(biāo)識(shí)相同的時(shí)候,才滿足互斥。如果上述代碼中線程2@synchronized(obj)中的標(biāo)識(shí)和線程1的不一樣,那么線程2不會(huì)被阻塞。

pthread_mutex_t

pthread_mutex_t是posix下的一個(gè)鎖類型,如果熟悉linux c編程的話會(huì)對(duì)這個(gè)比較熟悉。在iOS下使用也是一樣的,代碼如下:

- (void)pthreadDemo {
    TestObject *obj = [[TestObject alloc] init];

    __block pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        pthread_mutex_lock(&mutex);
        [obj method1];
        sleep(5);
        pthread_mutex_unlock(&mutex);
    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        pthread_mutex_lock(&mutex);
        [obj method2];
        pthread_mutex_unlock(&mutex);
    });
}

注意: 由于pthread_mutex_t是posix下的API,所以要引入相應(yīng)的頭文件#import <pthread.h>

dispatch_semaphore_t

dispatch_semaphore_t是GCD里面的一個(gè)信號(hào)量機(jī)制,也可以用來做線程同步。其相關(guān)的方法主要有:

dispatch_semaphore_t dispatch_semaphore_create(long value);
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
long dispatch_semaphore_signal(dispatch_semaphore_t dsema);

dispatch_semaphore_create:創(chuàng)建一個(gè)新的信號(hào)量,value代表信號(hào)量資源的數(shù)量.
dispatch_semaphore_wait: 等待資源釋放,如果此時(shí)dsema大于0,獲得資源,繼續(xù)執(zhí)行,并將信號(hào)量減1。如果dsema=0,阻塞當(dāng)前線程直到其他線程調(diào)dispatch_semaphore_signal釋放信號(hào)量。如果一直等不到信號(hào)量,則到timeout之后再繼續(xù)執(zhí)行。
dispatch_semaphore_signal:釋放一個(gè)資源。

使用代碼如下:

- (void)semaphoreDemo {
    TestObject *obj = [[TestObject alloc] init];

    dispatch_semaphore_t semphore = dispatch_semaphore_create(1);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
        [obj method1];
        sleep(5);
        dispatch_semaphore_signal(semphore);
    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        dispatch_semaphore_wait(semphore, DISPATCH_TIME_FOREVER);
        [obj method2];
        dispatch_semaphore_signal(semphore);
    });
}
最后編輯于
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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