iOS 底层探索篇 ——八大锁的分析

1. 锁的类型

自旋锁:线程反复检查锁变量是否可用。由于线程在这一过程中保持执行, 因此是一种忙等待。一旦获取了自旋锁,线程会一直保持该锁,直至显式释放自旋锁。 自旋锁避免了进程上下文的调度开销,因此对于线程只会阻塞很短时间的场合是有效的。

互斥锁:是一种用于多线程编程中,防止两条线程同时对同一公共资源(比 如全局变量)进行读写的机制有互斥和同步两个特点。当一个线程在进行任务的时候,别的线程就不能进行这个任务,这就是互斥。别的线程按照一定的顺序在这个线程完成后执行,这就是同步。该目的通过将代码切片成一个一个的临界区而达成,互斥锁分为递归锁和非递归锁。这里属于互斥锁的有:

  • NSLock
  • pthread_mutex
  • @synchronized

条件锁:就是条件变量,当进程的某些资源要求不满足时就进入休眠,也就是锁住了。当资源被分配到了,条件锁打开,进程继续运行

  • NSCondition
  • NSConditionLock

递归锁:就是同一个线程可以加锁N次而不会引发死锁

  • NSRecursiveLock
  • pthread_mutex(recursive)

信号量(semaphore):是一种更高级的同步机制,互斥锁可以说是 semaphore 在仅取值0/1时的特例。信号量可以有更多的取值空间,用来实现更加复杂的同步,而不单单是线程间互斥。

  • dispatch_semaphore

其实基本的锁就包括了三类 自旋锁 互斥锁 读写锁
其他的比如条件锁,递归锁,信号量都是上层的封装和实现!

2. 锁的应用

这里的代码运行后会奔溃,崩溃的主要原因是testArray在某一瞬间变成了nil。
在这里插入图片描述
在这里插入图片描述
下面这段代码如果执行的话,就会有10个testMethod(10)在异步执行,那么如何确保他们一个接一个执行呢?也就是应该怎么加锁呢?
在这里插入图片描述
在这里插入图片描述
这里把锁加在testMethod(10)前后就解决了问题,这里也可以在testMethod声明之后加锁。这里不能在testMethod的代码块里面加锁,否则就会递归加锁,而NSLock不支持递归加锁。
在这里插入图片描述
那么如果加了递归锁,是否可以这样加锁呢?答案也是不行的,因为这里面是多线程环境,递归锁无法进行多线程可递归。而要多线程,可递归,则需要用@synchronized锁。
在这里插入图片描述
这里看到加了@synchronized锁之后是正常运行的。

3. 锁的底层实现

看到NSLock,这里面是遵守了NSLockin

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值