iOS三种线程锁

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
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 锁是一种同步机制,用于多线程环境中对资源访问的限制iOS中常见锁的性能对比图(摘自:ibireme): iOS锁的...
    LiLS阅读 5,423评论 0 6
  • 前言 一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同...
    WQ_UESTC阅读 4,383评论 0 5
  • 在平时的开发中经常使用到多线程,在使用多线程的过程中,难免会遇到资源竞争的问题,那我们怎么来避免出现这种问题那? ...
    IAMCJ阅读 8,377评论 2 25
  • 自旋锁和互斥锁 共同点:都能保证同一时刻只能有一个线程操作锁住的代码。都能保证线程安全。不同点: 互斥锁(mute...
    中轴线_lz阅读 4,057评论 0 0
  • 转自: iOS 常见知识点(三):Lock NSLock NSLock 遵循 NSLocking 协议,lock ...
    MaybeLove00阅读 4,714评论 1 1