var tickets = 10000
let lockString = "lockString"
///objc_sync_enter(lockString)
///objc_sync_exit(lockString)
///同步锁,当同步锁上锁后,下一个线程企图访问资源,会被return掉,而不是等待
func buyTicket(username: String) {
DispatchQueue.global().async {
///加上互斥锁,保护资源 同一时刻只能被一个线程读写
print("\(username)来买票")
objc_sync_enter(lockString)
tickets -= 1
print("\(username)买了一张票,剩余票数:\(tickets)")
objc_sync_exit(lockString)
}
}
for i in 0...200 {
buyTicket(username: "person\(i)")
}
输出:
person0来买票
person2来买票
person0买了一张票,剩余票数:9999
person3来买票
person3买了一张票,剩余票数:9998
person4来买票
person4买了一张票,剩余票数:9997
person5来买票
person5买了一张票,剩余票数:9996
person6来买票
person6买了一张票,剩余票数:9995
person7来买票
person7买了一张票,剩余票数:9994
person8来买票
person8买了一张票,剩余票数:9993
person9来买票
person9买了一张票,剩余票数:9992
person10来买票
person10买了一张票,剩余票数:9991
person11来买票
person11买了一张票,剩余票数:9990
person12来买票
person12买了一张票,剩余票数:9989
person13来买票
person13买了一张票,剩余票数:9988
**重点分析:**多人排队来买票,有人买到了,有人没买到,后边来的人看到窗口正忙,就走了,下下个人到窗口前查看,直到最后一个人。
而不是下一个人等前一个人买完再去买()
dispatchOnce实现
extension DispatchQueue {
fileprivate static var _onceToken = [String]()
func once(token: String, _ block: () -> Void) {
objc_sync_enter(self)
defer {
objc_sync_exit(self)
}
if DispatchQueue._onceToken.contains(token) {
return
}
DispatchQueue._onceToken.append(token)
block()
}
}
利用互斥锁,没啥说的