GCD大家用的都比较多,但有时候却搞不太清楚同步异步,并行串行各种组合的应用场景,最近整理了一下。
/*
总结放在前边,如有不对的地方还请指教
名词解释:
同步:不开辟新线程(在当前线程)
异步:开辟新的线程(在新的线程)
串行:(在同一个线程)有序执行
并行:(在多个线程)无序执行
理解:
如果没有开辟新的线程,在当前线程中就只能FIFO,所以同步并行实际也还是串行执行的(并行和异步绑定使用才是有效的)
坑:
”串行&异步“或者”异步&串行“感觉是一样的 后来发现 ”异步串行“这样记才更容易理解如下:
异步串行=开辟新的线程并有序执行(开辟一条新线程有序执行)
异步并行=开辟新的线程&无序执行(开辟多条新线程无序执行)
同步串行=不开辟新线程&有序执行(没有新的线程只能在当前线程有序执行)
同步并行=不开辟新线程&无序执行(没有新的线程只能在当前线程有序执行)
a异步全局队列:
1.创建多个线程
2.无序执行
总结:适用于没有相互依赖关系的网络请求,既单独的网络请求,如:加载一个列表数据
b异步并行队列:(异步全局队列也是并行队列,但是全局队列没有名字不用管理可以直接使用)
1.创建多个线程
2.无序执行
总结:如a
c同步并行队列:
1.不会创建新的线程
2.在当前线程FIFO
总结:没用
d异步串行队列:
1.会创建一条新线程
2.在新的线程上FIFO
总结:适用于相互依赖的网络请求,既下一个任务依赖当前任务,如:图片上传完成后才能发布一条内容《可能例子不太恰当,正常操作可能是图片完成后在回调中直接做发布操作》
e同步串行队列:
1.不会创建新线程
2.在当前线程上FIFO
总结:没用
也就是说基本上只有异步操作的时候才需要用到GCD,其他情况实际上都是在当前线程有序执行的
*/
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.globalAsyncQueue()
}
func globalAsyncQueue() {
print("异步全局队列")
//全局队列
let globalQueue = DispatchQueue.global()
let globalQueueGroup = DispatchGroup()
for i in 0..<10 {
globalQueueGroup.enter()
globalQueue.async(execute: {
print("\(Thread.current.description)\(i)")
globalQueueGroup.leave()
})
}
globalQueueGroup.notify(queue: DispatchQueue.main) {
self.concurrentAsyncQueue()
}
/*
异步全局队列:
1.创建多个线程
2.无序执行
*/
}
func concurrentAsyncQueue() {
print("异步并行队列")
//并行队列
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: DispatchQueue.Attributes.concurrent)
let concurrentQueueGroup = DispatchGroup()
for i in 0..<10 {
concurrentQueueGroup.enter()
concurrentQueue.async(execute: {
print("\(Thread.current.description)\(i)")
concurrentQueueGroup.leave()
})
}
//任务完成后,通知主线程
concurrentQueueGroup.notify(queue: DispatchQueue.main) {
self.concurrentSyncQueue()
}
/*
异步并行队列:(异步全局队列也是并行队列类似,但是全局队列没有名字不用管理可以直接使用)
1.创建多个线程
2.无序执行
*/
}
func concurrentSyncQueue() {
print("同步并行队列")
//并行队列
let concurrentQueue = DispatchQueue(label: "concurrentSyncQueue", attributes: DispatchQueue.Attributes.concurrent)
let concurrentQueueGroup = DispatchGroup()
for i in 0..<10 {
concurrentQueueGroup.enter()
concurrentQueue.sync(execute: {
// Thread.sleep(forTimeInterval: 0.3)
print("\(Thread.current.description)\(i)")
concurrentQueueGroup.leave()
})
}
//任务完成后,通知当前线程
concurrentQueueGroup.notify(queue: concurrentQueue) {
self.serialAsyncQueue()
}
/*
同步并行队列:
1.不会创建新的线程
2.在当前线程FIFO
*/
}
func serialAsyncQueue() {
print("异步串行队列")
//串行队列
let serialQueue = DispatchQueue(label: "serialQueue")
let serialQueueGroup = DispatchGroup()
for i in 0..<10 {
serialQueueGroup.enter()
serialQueue.async(execute: {
print("\(Thread.current.description)\(i)")
serialQueueGroup.leave()
})
}
//任务完成后,通知主线程
serialQueueGroup.notify(queue: DispatchQueue.main) {
self.serialSyncQueue()
}
/*
异步串行队列:
1.会创建一条新线程
2.在新的线程上FIFO
*/
}
func serialSyncQueue() {
print("同步串行队列")
//串行队列
let serialQueue = DispatchQueue(label: "serialSyncQueue")
let serialQueueGroup = DispatchGroup()
for i in 0..<10 {
serialQueueGroup.enter()
serialQueue.sync(execute: {
// Thread.sleep(forTimeInterval: 0.3)
print("\(Thread.current.description)\(i)")
serialQueueGroup.leave()
})
}
serialQueueGroup.notify(queue: DispatchQueue.main) {
self.mainAsyncQueue()
}
/*
同步串行队列:
1.不会创建新线程
2.在当前线程上FIFO
*/
}
func mainAsyncQueue() {
print("异步主线程队列")
//串行队列
let mainQueue = DispatchQueue.main
let mainQueueGroup = DispatchGroup()
for i in 0..<10 {
mainQueueGroup.enter()
mainQueue.async(execute: {
// Thread.sleep(forTimeInterval: 0.3)
print("\(Thread.current.description)\(i)")
mainQueueGroup.leave()
})
}
mainQueueGroup.notify(queue: DispatchQueue.main) {
self.mainSyncQueue()
}
/*
异步主线程队列:
1.因为主线程只有一个,所以不会创建新线程
2.在主线程上FIFO
*/
}
func mainSyncQueue() {
print("同步主线程队列,会发生crash,线程死锁,想要测试可以注释return")
//会发生crash,线程死锁
return
//串行队列
let mainQueue = DispatchQueue.main
let mainQueueGroup = DispatchGroup()
for i in 0..<10 {
mainQueueGroup.enter()
mainQueue.sync(execute: {
// Thread.sleep(forTimeInterval: 0.3)
print("\(Thread.current.description)\(i)")
mainQueueGroup.leave()
})
}
mainQueueGroup.notify(queue: DispatchQueue.main) {
print("执行完成")
}
/*
同步主线程队列:
1.不会创建新线程
2.在当前线程上FIFO
*/
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}