面试题iOS的技术论坛iOS优秀开发文章

iOS三种线程锁

2019-06-18  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读