多線程鎖的使用

方法一:用NSLock

TestObj *obj = [[TestObj alloc] init];
//線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [lock lock];
        [obj method1];
        sleep(30);
        [lock unlock];
    });
    
    //線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(5);//以保證讓線程2的代碼后執(zhí)行
        [lock lock];
        [obj method2];
        [lock unlock];
    });

方法二:用@synchronized

TestObj *obj = [[TestObj alloc] init];
    //線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        @synchronized (obj) {
            [obj method1];
        }
        sleep(30);
    });
    
    //線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(5);//以保證讓線程2的代碼后執(zhí)行
        @synchronized (obj) {
            [obj method2];
        }
    });

方法三:用GCD的dispatch_semaphore_t和dispatch_semaphore_wait

  • dispatch_semaphore_create(num),這里的num相當于古代將軍發(fā)的令牌數(shù)目,如果num是1,表示可以分配給一個將領(lǐng)去執(zhí)行任務(wù),實例代碼代碼如下:
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"method1");
        sleep(10);
        dispatch_semaphore_signal(semaphore);
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"method2");
        dispatch_semaphore_signal(semaphore);
    });

這里dispatch_semaphore_create(1)創(chuàng)建的是一個令牌,所以會先執(zhí)行method1任務(wù),然后等待10秒后發(fā)送一個信號(dispatch_semaphore_signal(semaphore))使信號量+1,再執(zhí)行method2任務(wù)

  • num如果是0,沒有令牌,就立即執(zhí)行dispatch_semaphore_wait方法:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"method1");
        sleep(10);
        dispatch_semaphore_signal(semaphore);
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"method2");
        dispatch_semaphore_signal(semaphore);
    });

這里只執(zhí)行到dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);,永遠不會執(zhí)行NSLog(@"method1")和下面的method2方法

  • num如果是2,分配2個令牌,使得下面兩個進程都可以執(zhí)行:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"method1");
        sleep(10);
        dispatch_semaphore_signal(semaphore);
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"method2");
        dispatch_semaphore_signal(semaphore);
    });

方法三:用pthread_mutex互斥鎖

  • 初始化
    導(dǎo)入#import <pthread.h>
@interface XYThread ()
{
    pthread_mutex_t mutex;  //聲明pthread_mutex_t的結(jié)構(gòu)
}
@end

//在viewDidLoad里初始化
- (void)viewDidLoad {
    [super viewDidLoad];
    pthread_mutex_init(&mutex, NULL);
}
  • 加鎖and解鎖
//加鎖
pthread_mutex_lock(&mutex);

/*你的代碼*/

//解鎖
pthread_mutex_unlock(&mutex);
  • 釋放鎖
- (void)dealloc{
    pthread_mutex_destroy(&mutex);  //釋放該鎖的數(shù)據(jù)結(jié)構(gòu)
}

針對函數(shù)遞歸調(diào)用的情況,可以使用遞歸鎖

- (void)viewDidLoad {
    NSMutableArray *array = @[].mutableCopy;
    
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);//定義鎖的類別
    __block pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, &attr);
        pthread_mutexattr_destroy (&attr);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        pthread_mutex_lock(&mutex);
        [array addObject:@"1"];
        [NSThread sleepForTimeInterval:1];
        NSLog(@"thread1");
        pthread_mutex_unlock(&mutex);
    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        pthread_mutex_lock(&mutex);
        [array addObject:@"2"];
        [NSThread sleepForTimeInterval:2];
        NSLog(@"thread2");
        pthread_mutex_unlock(&mutex);
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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