367 字
2 分钟
锁|NSConditionLock
一、 NSConditionLock
先来看一个面试题,下面代码输出的顺序会是什么样。
let conditionLock = NSConditionLock(condition: 2)let queue1 = DispatchQueue.global(qos: .unspecified)let queue2 = DispatchQueue.global(qos: .background)let queue3 = DispatchQueue.global(qos: .default)
queue1.async { conditionLock.lock(whenCondition: 1) print("1") conditionLock.unlock(withCondition: 0)}
queue2.async { conditionLock.lock(whenCondition: 2) print("2") conditionLock.unlock(withCondition: 1)}
queue3.async { conditionLock.lock() print("3") conditionLock.unlock()}1.1 API 简单介绍
相信很多同学和我一样没怎么用过这个锁,对着几个API也是蒙的。下面就先介绍一下这些API吧。
- lock(whenCondition:)
- 在锁定操作成功之前,接收者的条件必须等于
Condition。 这个方法会阻塞线程的执行,直到可以获取到锁,即满足Condition。
- 在锁定操作成功之前,接收者的条件必须等于
- unlock(withCondition:)
- 解锁并设置
Condition
- 解锁并设置
- lock
- 如果没有其他线程获得锁那它能执⾏此⾏以下代码,如果已经有其他线程获得锁,则等待,直⾄其他线程解锁
- unlock
- 解锁
1.2 分析
queue1 、 queue2 、 queue3根据优先级从高到低: queue1 > queue3 > queue2
如果不看锁的部分,执行的顺序大概率是 1 3 2。但是这里有锁,所以这里的优先级是一个迷惑项。
执行步骤如下:
- condition = 2
- 满足 2 的进入条件,但是
queue3优先级更高,所以 3 大概率优先输出 - 3 输出
- condition 不变
- 满足 2 的进入条件,但是
- condition 满足 2 的条件
- 可以执行 2
- 2 输出
- 解锁 condition = 1
- condition 满足 1 的条件
- 可以执行 1
- 1 输出
- 解锁 condition = 0
