术语

同步:【相对于任务而言】按顺序执行多个任务,在一个线程里按顺序执行,结束顺序是固定的。

异步:【相对于任务而言】按顺序执行多个任务,在多个线程里执行,结束的顺序是随机的。

串行:【相对于队列而言】多个任务在串行队列里执行,按顺序执行。

并发:【相对于队列而言】多个任务在并行队列里执行,同时执行。

GCD

1、串行队列

let q = DispatchQueue(label: "com.example.1")

2、并发队列

let q = DispatchQueue(label: "com.example.2", attributes: .concurrent)

3、主队列

let main = DispatchQueue.main

4、全局队列

let global = DispatchQueue.global()

队列优先级

名称 注释
.userInteractive 和用户交互,优先级最高。场景:界面绘图
.userInitiated 立即发生。场景:用户点击按钮
.default 默认
.utility 一些计算任务,场景:连续数据处理
.background 后台任务,场景:一些日志,同步服务等
.unspecified 用于兼容旧版 API,因为有些旧版 API 可能会使线程超出 QoS 范围

5、添加任务

q.async {
    /// 异步执行
}
q.sync {
    /// 同步执行
}

6、线程死锁

let q = DispatchQueue(label: "com.example.3", attributes: .concurrent)
q.sync {
    DispatchQueue.main.sync {
    }
}

DispatchGroup

Group 管理多个队列

执行顺序不确定

let group = DispatchGroup()
let requestQueue = DispatchQueue(label: "com.example.request", qos: .background)
let calculateQueue = DispatchQueue(label: "com.example.calculate",qos: .utility)
let otherQueue = DispatchQueue(label: "com.example.other", qos: .default)
requestQueue.async(group: group) {
    /// 任务
}
calculateQueue.async(group: group) {
    /// 任务
}
otherQueue.async(group: group) {
    ///
}
// 任务全部结束,在指定队列通知
group.notify(queue: .main) {
    print("all done")
}

await() 线程等待,超时时间

let g = DispatchGroup()
let q = DispatchQueue(label: "com.example.await", attributes: .concurrent)
q.async(group: g) {
    Thread.sleep(forTimeInterval: 5)
}
q.async(group: g) {
    Thread.sleep(forTimeInterval: 2)
}
if g.wait(timeout: .now() + 6) == .success {
    print("sucess")
} else {
    print("timeout")
}

enter() 和 leave() 队列里面的任务执行完成之后默认会通知 Group, 但是如果任务中还有异步任务需要手动通知 Group

let g = DispatchGroup()
let q = DispatchQueue.init(label: "com.ecample.enter_leave")
q.async(group: g) {
    print("1")
    g.enter()
    DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
        print("2")
        g.leave()
    }
    print("3")
}
g.notify(queue: .main) {
    print("done")
}

DispatchSemaphore

let d = DispatchSemaphore(value: 1)
let q = DispatchQueue.global(qos: .background)

q.async {
    d.wait() // 信号量 -1
    DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
        print("1")
        d.signal() // 信号量 +1
    }
}

q.async {
    d.wait()
    DispatchQueue.global().asyncAfter(deadline: .now() + 5) {
        print("2")
        d.signal()
    }
}

q.async {
    d.wait()
    DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
        print("3")
        d.signal()
    }
}