美文网首页
Objective-C中锁的几种实现方式

Objective-C中锁的几种实现方式

作者: 跃文 | 来源:发表于2019-04-25 15:25 被阅读0次

锁的意义就是为了防止在多线程(多任务)的情况下对共享资源(临界资源)的脏读或者脏写。也可以理解为:用于执行多线程操作时强行限制资源访问的同步机制,即并发控制中保证互斥的要求,可以理解成它用于排除并发的一种策略。

分类方式 分类
按锁的粒度划分 表级锁、行级锁、页级锁
按锁的级别划分 共享锁、排他锁
按加锁方式划分 自动锁、显示锁
按锁的使用方式划分 乐观锁、悲观锁
按操作划分 DML锁、DDL锁
等等。。 等等。。
方式1 使用NSLock类
  • 该类分成了几个子类:NSLock、NSConditionLock(条件锁)、NSRecursiveLock(递归锁)以及NSCondition。
  • 类内方法:
    tryLock:作用是尝试获取一个锁,并且立刻返回Bool值,YES表示获取了锁,NO表示没有获取锁失败。
    lockBeforeDate::作用是在某个时刻之前获取锁,如果获取成功,则返回YES,NO表示获取锁失败。
- (void)lockDemo1 {
    NSLock *myLock = [[NSLock alloc] init];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [myLock lock];
        NSLog(@"执行锁1");
        sleep(5);
        [myLock unlock];
        if ([myLock tryLock]) {
            NSLog(@"可以获得锁1");
        }else {
            NSLog(@"不可以获得锁1");
        }
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        if ([myLock tryLock]) {
            NSLog(@"---可以获得锁2");
        }else {
            NSLog(@"----不可以获得所2");
        }
        [myLock lock];
        NSLog(@"执行锁2");
        [myLock unlock];
    });
}
方式2 使用@synchorize
  • 对于@synchorize指令中使用的testLock为该锁标示,只有标示相同的时候才满足锁的效果。它的优点是不用显式地创建锁,便可以实现锁的机制。但是它会隐式地添加异常处理程序来保护代码,该程序在抛出异常的时候自动释放锁。
- (void)lockDemo2 {
   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       @synchronized (self) {
           NSLog(@"执行锁1");
           sleep(5);
       }
   });
   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       sleep(1);
       @synchronized (self) {
           NSLog(@"执行锁2");
       }
   });
}
方式3 使用gcd
- (void)lockDemo3 {
    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(@"执行锁1");
        sleep(5);
        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(@"执行锁2");
        dispatch_semaphore_signal(semaphore);
    });
}
方式4 使用phtread
- (void)lockDemo4 {

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

    //线程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        pthread_mutex_lock(&mutex);
        NSLog(@"执行锁1");
        sleep(5);
        pthread_mutex_unlock(&mutex);
    });

    //线程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        pthread_mutex_lock(&mutex);
        NSLog(@"执行锁2");
        pthread_mutex_unlock(&mutex);
    });
}
方式5 OSSpinLock
- (void)lockDemo4 {

    OSSpinLock spinlock = OS_SPINLOCK_INIT;

    //线程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        OSSpinLockLock(&spinlock);
        NSLog(@"执行锁1");
        sleep(5);
        OSSpinLockUnlock(&spinlock);
    });

    //线程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        OSSpinLockLock(&spinlock);
        NSLog(@"执行锁2");
        OSSpinLockUnlock(&spinlock);
    });
}
同样加锁解锁次数耗时结果比较:

OSSpinlock < pthread_mutex < NSLock+IMP < NSLock < @synchronized

  • 1、@synchronized
    内部会创建一个异常捕获的handler和其他内部使用的锁。由于内部会添加异常处理,所以耗时。
  • 2、NSLock 和 NSLock+IMP
    两个时间非常接近。他们是 pthread mutexes 封装的,但是创建对象的时候需要额外的开销。
  • 3、pthread_mutex
    底层的API,性能比较高,处理能力不错。
  • 4、gcd
    系统封装的C代码效果比pthread好。
  • 5、OSSpinLock
    自旋锁不进入内核,仅仅是重新加载。如果自旋锁占用的时间是极少的(通常是纳秒级别的)性能还是比较高的,减少了系统的直接调用和上下文的切换。(因为优先级倒置问题已经弃用,此类已经被os_unfair_lock所替)

耗时结果如下: synthorize > NSLock > pthread > gcd > os_unfair_lock >OSSPinLock

相关文章

  • Objective-C中锁的几种实现方式

    锁的意义就是为了防止在多线程(多任务)的情况下对共享资源(临界资源)的脏读或者脏写。也可以理解为:用于执行多线程操...

  • 数据库实现分布式锁

    在之前的文章中记录Java中锁和AOP的相关实现,最后列出了分布式锁的几种实现方式但是没有详细说明,这篇文章对数据...

  • 分布式锁

    几种实现方式 基于数据库实现分布式锁 基于缓存(Redis,memcached,tair)实现分布式锁 基于Zoo...

  • @synchronized 的原理探究

    使用 @synchronized (递归互斥锁) Objective-C 代码中动态创建互斥锁的便捷方式。该 @...

  • 分布式锁实现

    1 基本的实现方式 分布式锁的主要实现方式主要有以下几种:mysql,zookeeper和redis。下面依次介绍...

  • iOS各种锁简介(上)

    iOS各种锁简介(上) 本篇文章主要介绍iOS中几种不同的锁的实现方式,既然是简介,这里不会涉及到原理上面的东西,...

  • Objective-C中不同方式实现锁

    为什么需要使用锁,当然熟悉多线程的你,自然不会对它觉得陌生。 那你在代码中是否很好的使用了锁的机制呢?你又知道几种...

  • 锁(2)-- 分布式锁

    前言: 锁分3种:java锁、分布式锁、DB锁 分布式锁的几种实现方式 目前几乎很多大型网站及应用都是分布式部署...

  • Redis锁机制的几种实现方式

    1. redis加锁分类 redis能用的的加锁命令分表是INCR、SETNX、SET 2. 第一种锁命令INCR...

  • 7.2-基于Redis实现分布式锁的几种坑你是否踩过《上》—小滴

    基于Redis实现分布式锁的几种坑你是否踩过《上》 简介:基于Redis实现分布式锁的几种坑 实现分布式锁 可以用...

网友评论

      本文标题:Objective-C中锁的几种实现方式

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