DispatchQueue 三种类型
- Main Queue 主队列,串行
- Global Queue 全局队列,并行
- Custom Queue 自定义队列,默认串行
let mainQueue = DispatchQueue.main
let globalQueue = DispatchQueue.global()
let customSerialQueue = DispatchQueue(label: "serialQueue")
let customConcurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
GCD 线程的同步 enter - leave - notify
当我们想要在并发结束后再同步执行东西。首先我们声明一个线程组 DispatchGroup。
import Foundation
let group = DispatchGroup()
let queue = DispatchQueue(label: "concurrent", attributes: .concurrent)
group.enter()
queue.async {
sleep(5)
print("任务一完成")
group.leave()
}
group.enter()
queue.async {
sleep(8)
print("任务二完成")
group.leave()
}
group.notify(queue: .main) {
print("最后的任务")
}
print("Start")
直接用队列方法里的 group 参数也可以达到上面 enter() 和 leave() 的效果,但前提是闭包里执行的得是同步任务才可以。
import Foundation
let group = DispatchGroup()
let queue = DispatchQueue(label: "concurrent", attributes: .concurrent)
queue.async(group: group, qos: DispatchQoS.default) {
sleep(5)
print("任务一")
}
queue.async(group: group, qos: DispatchQoS.default) {
sleep(8)
print("任务二")
}
group.notify(queue: .main) {
print("最后的任务")
}
print("Start")
DispatchSemaphore
串行的执行两个异步线程
import Foundation
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
semaphore.wait()
print("1")
}
DispatchQueue.global().async {
sleep(2)
print("2")
semaphore.signal()
}
//打印输出为 2,1
DispatchQoS
- userInteractive: 与用户交互相关的任务,要最重视,优先处理,保证界面最流畅
- userInitiated: 用户主动发起的任务,要比较重视
- default: 默认任务,正常处理即可
- utility: 用户没有主动关注的任务
- background: 不太重要的维护、清理等任务,有空能处理完就行
- unspecified: 别说身份了,连身份证都没有,能处理就处理,不能处理也无所谓的
线程安全
自定义队列支持设置 flags 为 .barrier,可以支持 barrier 之前的任务全部执行完毕后,再执行 .barrier 任务,最后再执行 .barrier 之后的任务。
import Foundation
// 创建一个并发队列
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
// 模拟一个共享资源
var sharedResource = [String]()
// 读操作
func readResource() {
concurrentQueue.async {
print("Read operation started")
let resourceCopy = sharedResource // 读取操作
print("Read operation completed: \(resourceCopy)")
}
}
// 写操作
func writeResource(item: String) {
concurrentQueue.async(flags: .barrier) {
print("Write operation started")
sharedResource.append(item) // 写入操作
print("Write operation completed: \(sharedResource)")
}
}
// 模拟并发读写操作
for i in 1...5 {
readResource()
writeResource(item: "Item \(i)")
}