GCD / OperationQueue
/**
总结GCD:
Q:实现任务之间有一定的执行顺序?
1. 最简单的任务嵌套
1. 异步串形队列,保证执行顺序
2. 栅栏函数
3. DispatchGroup组, 组通知group_notify
Q:并发队列同步执行耗时任务的问题?
会导致主线程卡住,不建议这么写
Q: 主队列执行同步任务的问题?
卡死,崩溃
Q: 全局队列使用栅栏函数会生效吗?
不会生效。
总结 OperationQueue:
⚠️ OperationQueue在对GCD的异步并发/串行队列的优化。
写法简单:任务的并发/串行/任务依赖关系/取消未执行任务
*/
主队列
//MARK: 主队列
func 同步主串行队列() {
let queue = DispatchQueue.main
queue.sync {
print("---task1 \(Thread.current)")
}
queue.sync {
print("---task2 \(Thread.current)")
}
queue.sync {
print("---task3 \(Thread.current)")
}
queue.sync {
print("---task4 \(Thread.current)")
}
/** 执行结果: 崩溃
*/
}
全局队列
//MARK: 全局队列
func 同步全局并发队列() {
let queue = DispatchQueue.global()
queue.sync {
print("---task1 \(Thread.current)")
}
queue.sync {
print("---task2 \(Thread.current)")
}
queue.sync {
print("---task3 \(Thread.current)")
}
queue.sync {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 -> task2 -> task3 -> task4
---task1 <_NSMainThread: 0x600003978040>{number = 1, name = main}
---task2 <_NSMainThread: 0x600003978040>{number = 1, name = main}
---task3 <_NSMainThread: 0x600003978040>{number = 1, name = main}
---task4 <_NSMainThread: 0x600003978040>{number = 1, name = main}
*/
}
func 异步全局并发队列() {
let queue = DispatchQueue.global()
queue.async {
print("---task1 \(Thread.current)")
}
queue.async {
print("---task2 \(Thread.current)")
}
queue.async {
print("---task3 \(Thread.current)")
}
queue.async {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 | task2 | task3 | task4
*/
}
func 异步全局并发队列加栅栏() {
let queue = DispatchQueue.global()
queue.async {
print("---task1 \(Thread.current)")
}
//⚠️全局队列加栅栏函数不会阻塞队列任务
queue.async(group: nil, qos: .default, flags: .barrier) {
print("---task2 \(Thread.current)")
sleep(3)
}
queue.async {
print("---task3 \(Thread.current)")
}
queue.async {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 | task2 | task3 | task4
---task3 <NSThread: 0x600001cdc400>{number = 5, name = (null)}
---task4 <NSThread: 0x600001cdc400>{number = 5, name = (null)}
---task1 <NSThread: 0x600001cdd200>{number = 9, name = (null)}
---task2 <NSThread: 0x600001cdc400>{number = 5, name = (null)}
*/
}
自定义串形队列
//MARK: 自定义串形队列
func 同步串行队列() {
let queue = DispatchQueue(label: "serial_queue", attributes: .concurrent)
queue.sync {
print("---task1 \(Thread.current)")
}
queue.sync {
print("---task2 \(Thread.current)")
}
queue.sync {
print("---task3 \(Thread.current)")
}
queue.sync {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 -> task2 -> task3 -> task4
---task1 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
---task2 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
---task3 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
---task4 <_NSMainThread: 0x6000020f00c0>{number = 1, name = main}
*/
}
func 异步串行队列() {
let queue = DispatchQueue(label: "serial_queue")
queue.async {
print("---task1 \(Thread.current)")
}
queue.async {
print("---task2 \(Thread.current)")
}
queue.async {
print("---task3 \(Thread.current)")
}
queue.async {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 -> task2 -> task3 -> task4
---task1 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
---task2 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
---task3 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
---task4 <NSThread: 0x6000030baf80>{number = 6, name = (null)}
*/
}
自定义并发队列
//MARK: 自定义并发队列
func 同步并发队列() {
print("start")
let queue = DispatchQueue(label: "concurrent_queue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
for i in 1...10 {
//⚠️ 会导致主线程卡住,不建议这么写
queue.sync {
sleep(UInt32(Int.random(in: 0...10)))
print("task \(i) in \(Thread.current)")
}
}
queue.async {
print("taskxxx in \(Thread.current)")
}
print("end")
/** 执行结果: 按序执行
start
task 1 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 2 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 3 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 4 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 5 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 6 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 7 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 8 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 9 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
task 10 in <_NSMainThread: 0x600003ddc140>{number = 1, name = main}
end
taskxxx in <NSThread: 0x600003dca1c0>{number = 3, name = (null)}
*/
}
func 异步并发队列() {
let queue = DispatchQueue(label: "concurrent_queue", attributes: .concurrent)
queue.async {
print("---task1 \(Thread.current)")
}
queue.async {
print("---task2 \(Thread.current)")
}
queue.async {
print("---task3 \(Thread.current)")
}
queue.async {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 | task2 | task3 | task4
---task4 <NSThread: 0x6000034e8a80>{number = 3, name = (null)}
---task2 <NSThread: 0x6000034fc180>{number = 7, name = (null)}
---task1 <NSThread: 0x6000034ea9c0>{number = 5, name = (null)}
---task3 <NSThread: 0x600003485cc0>{number = 6, name = (null)}
*/
}
func 异步并发队列中使用栅栏函数() {
let queue = DispatchQueue(label: "concurrent_queue", attributes: .concurrent)
queue.async {
print("---task1 \(Thread.current)")
}
//栅栏函数
queue.async(group: nil, qos: .default, flags: .barrier) {
print("---task2 \(Thread.current)")
sleep(3)
}
queue.async {
print("---task3 \(Thread.current)")
}
queue.async {
print("---task4 \(Thread.current)")
}
/** 执行顺序: task1 -> task2 -> task3 | task4
---task1 <NSThread: 0x600001724c40>{number = 7, name = (null)}
---task2 <NSThread: 0x600001724c40>{number = 7, name = (null)}
---task4 <NSThread: 0x600001720740>{number = 3, name = (null)}
---task3 <NSThread: 0x600001724c40>{number = 7, name = (null)}
*/
}
队列组的使用
//MARK: 队列组的使用
func 队列组() {
let group = DispatchGroup()
let queue = DispatchQueue(label: "concurrent_queueu", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
queue.async {
print("---task1 \(Thread.current)")
sleep(3)
}
//方案1: 加入组 enter/leave
//进入组
group.enter()
queue.async {
print("---task2 \(Thread.current)")
//离开组
group.leave()
}
//方案1: 加入组
queue.async(group: group, execute: DispatchWorkItem(block: {
print("---task3 \(Thread.current)")
sleep(3)
}))
queue.async {
sleep(10)
print("---task4 \(Thread.current)")
}
// group.notify(queue: DispatchQueue.main, work: DispatchWorkItem(block: {
// print("---group notify \(Thread.current)")
// }))
group.notify(queue: queue, work: DispatchWorkItem(block: {
print("---group notify \(Thread.current)")
}))
/**执行顺序: 只能保证 group notify 在 {task2, task3} 的后面
---task1 <NSThread: 0x600003efe8c0>{number = 6, name = (null)}
---task3 <NSThread: 0x600003efd5c0>{number = 7, name = (null)}
---task2 <NSThread: 0x600003e83ec0>{number = 3, name = (null)}
---group notify <NSThread: 0x600003efe8c0>{number = 6, name = (null)}
---task4 <NSThread: 0x600003ef4900>{number = 4, name = (null)}
*/
}
func 嵌套任务() {
let queue = DispatchQueue(label: "concurrent_queue", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
queue.async {
sleep(10)
print("task1 \(Thread.current)")
queue.async {
print("task2 \(Thread.current)")
}
}
queue.async {
print("task3 \(Thread.current)")
}
queue.async {
print("task4 \(Thread.current)")
}
/** 执行结果: 只能保证task2在task1的后面
*/
}
OperationQueue
func 操作队列任务依赖() {
let queue = OperationQueue()
let operation1 = BlockOperation {
sleep(10)
print("task1 in \(Thread.current)")
}
let operation2 = BlockOperation {
print("task2 in \(Thread.current)")
}
let operation3 = BlockOperation {
print("task3 in \(Thread.current)")
}
let operation4 = BlockOperation {
print("task4 in \(Thread.current)")
}
//任务之间增加依赖方式简单
operation3.addDependency(operation1)
queue.addOperation(operation1)
queue.addOperation(operation2)
queue.addOperation(operation3)
queue.addOperation(operation4)
}
func 操作队列异步串行队列() {
let queue = OperationQueue()
//异步串行队列
queue.maxConcurrentOperationCount = 1
let operation1 = BlockOperation {
sleep(10)
print("task1 in \(Thread.current)")
}
let operation2 = BlockOperation {
print("task2 in \(Thread.current)")
}
let operation3 = BlockOperation {
print("task3 in \(Thread.current)")
}
let operation4 = BlockOperation {
print("task4 in \(Thread.current)")
}
queue.addOperation(operation1)
queue.addOperation(operation2)
queue.addOperation(operation3)
queue.addOperation(operation4)
}
func 操作队列任务栅栏() {
let queue = OperationQueue()
//异步串行队列
queue.maxConcurrentOperationCount = 1
//队列任务取消
DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: DispatchWorkItem(block: {
queue.cancelAllOperations()
}))
let operation1 = BlockOperation {
sleep(10)
print("task1 in \(Thread.current)")
}
let operation2 = BlockOperation {
print("task2 in \(Thread.current)")
}
let operation3 = BlockOperation {
print("task3 in \(Thread.current)")
}
let operation4 = BlockOperation {
print("task4 in \(Thread.current)")
}
queue.addOperation(operation1)
queue.addBarrierBlock {
print("task栅栏 in \(Thread.current)")
}
queue.addOperation(operation2)
queue.addOperation(operation3)
queue.addOperation(operation4)
/**
task1 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
task栅栏 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
task3 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
task4 in <NSThread: 0x6000022f4840>{number = 10, name = (null)}
task2 in <NSThread: 0x6000022962c0>{number = 4, name = (null)}
*/
}
func 操作队列任务的取消() {
let queue = OperationQueue()
//队列任务取消
DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: DispatchWorkItem(block: {
queue.cancelAllOperations()
}))
let operation1 = BlockOperation {
sleep(10)
print("task1 in \(Thread.current)")
}
let operation2 = BlockOperation {
print("task2 in \(Thread.current)")
}
let operation3 = BlockOperation {
print("task3 in \(Thread.current)")
}
let operation4 = BlockOperation {
print("task4 in \(Thread.current)")
}
queue.addOperation(operation1)
queue.addOperation(operation2)
queue.addOperation(operation3)
queue.addOperation(operation4)
}