GCD / OperationQueue
/**
總結(jié)GCD:
Q:實現(xiàn)任務之間有一定的執(zhí)行順序尿褪?
1. 最簡單的任務嵌套
1. 異步串形隊列办铡,保證執(zhí)行順序
2. 柵欄函數(shù)
3. DispatchGroup組, 組通知group_notify
Q:并發(fā)隊列同步執(zhí)行耗時任務的問題脐雪?
會導致主線程卡住付翁,不建議這么寫
Q: 主隊列執(zhí)行同步任務的問題?
卡死贮缅,崩潰
Q: 全局隊列使用柵欄函數(shù)會生效嗎榨咐?
不會生效。
總結(jié) OperationQueue:
?? OperationQueue在對GCD的異步并發(fā)/串行隊列的優(yōu)化谴供。
寫法簡單:任務的并發(fā)/串行/任務依賴關(guān)系/取消未執(zhí)行任務
*/
主隊列
//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)")
}
/** 執(zhí)行結(jié)果: 崩潰
*/
}
全局隊列
//MARK: 全局隊列
func 同步全局并發(fā)隊列() {
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)")
}
/** 執(zhí)行順序: 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 異步全局并發(fā)隊列() {
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)")
}
/** 執(zhí)行順序: task1 | task2 | task3 | task4
*/
}
func 異步全局并發(fā)隊列加柵欄() {
let queue = DispatchQueue.global()
queue.async {
print("---task1 \(Thread.current)")
}
//??全局隊列加柵欄函數(shù)不會阻塞隊列任務
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)")
}
/** 執(zhí)行順序: 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)")
}
/** 執(zhí)行順序: 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)")
}
/** 執(zhí)行順序: 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)}
*/
}
自定義并發(fā)隊列
//MARK: 自定義并發(fā)隊列
func 同步并發(fā)隊列() {
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")
/** 執(zhí)行結(jié)果: 按序執(zhí)行
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 異步并發(fā)隊列() {
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)")
}
/** 執(zhí)行順序: 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 異步并發(fā)隊列中使用柵欄函數(shù)() {
let queue = DispatchQueue(label: "concurrent_queue", attributes: .concurrent)
queue.async {
print("---task1 \(Thread.current)")
}
//柵欄函數(shù)
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)")
}
/** 執(zhí)行順序: 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)")
}))
/**執(zhí)行順序: 只能保證 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)")
}
/** 執(zhí)行結(jié)果: 只能保證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)
}