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

参考

Last updated