Links

31.锁|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 分析

queue1queue2queue3根据优先级从高到低: queue1 > queue3 > queue2
如果不看锁的部分,执行的顺序大概率是 1 3 2。但是这里有锁,所以这里的优先级是一个迷惑项。
执行步骤如下:
  • condition = 2
    • 满足 2 的进入条件,但是 queue3 优先级更高,所以 3 大概率优先输出
    • 3 输出
    • condition 不变
  • condition 满足 2 的条件
    • 可以执行 2
    • 2 输出
    • 解锁 condition = 1
  • condition 满足 1 的条件
    • 可以执行 1
    • 1 输出
    • 解锁 condition = 0
2

参考