iOS三种线程锁

作者: 宋魁鹏 | 来源:发表于2019-06-18 12:03 被阅读0次

    1.使用NSLock实现的锁

    NSLock是Cocoa提供给我们最基本的锁对象,这也是我们经常所使用的,除lock和unlock方法外,NSLock还提供了tryLock和lockBeforeDate:两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),刚并不会阻塞线程,并返回NO。lockBeforeDate:方法会在所指定Date之前尝试加锁,如果在指定时间之前都不能加锁,则返回NO。

    //NSLock锁
        NSLock *lock = [[NSLock alloc] init];
        
        //线程1
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [lock lock];
            NSLog(@"线程1开始");
            sleep(10);
            NSLog(@"线程1结束");
            [lock unlock];
        });
        //线程2
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(2);//以保证让线程2的代码后执行
            [lock lock];
            NSLog(@"线程2");
            [lock unlock];
        });
    

    打印结果

    2019-06-18 11:49:36.404882+0800 AAAAA[2249:112124] 线程1开始
    2019-06-18 11:49:46.409998+0800 AAAAA[2249:112124] 线程1结束
    2019-06-18 11:49:46.410351+0800 AAAAA[2249:112125] 线程2
    
    

    2.使用synchronized关键字构建的锁

    @synchronized指令实现锁的优点就是我们不需要在代码中显式的创建锁对象,便可以实现锁的机制,但作为一种预防措施,@synchronized块会隐式的添加一个异常处理例程来保护代码,该处理例程会在异常抛出的时候自动的释放互斥锁。所以如果不想让隐式的异常处理例程带来额外的开销,你可以考虑使用锁对象。

    UIView *other = [[UIView alloc] init];
        //线程1
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            @synchronized(self){
                NSLog(@"线程1开始");
                sleep(10);
                NSLog(@"线程1结束");
            }
        });
        //线程2
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(1);
            @synchronized(other){
                NSLog(@"线程2");
            }
        });
        //线程3
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(2);
            @synchronized(self){
                NSLog(@"线程3");
            }
        });
    

    打印结果

    2019-06-18 11:57:22.831604+0800 AAAAA[2363:119063] 线程1开始
    2019-06-18 11:57:23.834307+0800 AAAAA[2363:119066] 线程2
    2019-06-18 11:57:32.835082+0800 AAAAA[2363:119063] 线程1结束
    2019-06-18 11:57:32.835410+0800 AAAAA[2363:119070] 线程3
    
    

    3.使用GCD中“信号量”来实现的”锁”

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
        //线程1
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"线程1开始");
            sleep(10);
            NSLog(@"线程1结束");
            dispatch_semaphore_signal(semaphore);
        });
        //线程2
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(1);
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"线程2");
            dispatch_semaphore_signal(semaphore);
        });
    

    打印结果

    2019-06-18 12:02:14.863220+0800 AAAAA[2439:123901] 线程1开始
    2019-06-18 12:02:24.868817+0800 AAAAA[2439:123901] 线程1结束
    2019-06-18 12:02:24.869162+0800 AAAAA[2439:123900] 线程2
    

    相关文章

      网友评论

        本文标题:iOS三种线程锁

        本文链接:https://www.haomeiwen.com/subject/zaoxqctx.html