一.概念
串行(Serial)
多个任务放在串行队列里执行,只能按顺序依次运行,前一个运行完成,下一个才能开始运行;前一个没运行完,后一个只能排队等着。以此类推,直到所有任务都运行完成。
并发(Concurrency)
多个任务放在并行队列里执行,可以同时运行.
串行和并行描述的是 任务和任务之间 的执行方式;执行顺序不同,以及开启线程数不同。
并发和并行
-
并发:(Concurrency)
在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行(不断切换)。 -
并行:(Parallelism)
在操作系统中,一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的。
在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)。
而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)。
同步sync:
- 同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。
- 只能在当前线程中执行任务,不具备开启新线程的能力。
异步async:
- 异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务。
- 可以在新的线程中执行任务,具备开启新线程的能力。
两者的主要区别是:是否等待队列的任务执行结束,以及是否具备开启新线程的能力。
注意:异步执行(async)虽然具有开启新线程的能力,但是并不一定开启新线程。这跟任务所指定的队列类型有关。
异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段
二.iOS-GCD
Grand Central Dispatch简称GCD.好处此处不再多言,直接上代码
//定义四个调度任务,打印当前线程数据
let item1 = DispatchWorkItem {
for i in 0...4{
print("item1 -> \(i) thread: \(Thread.current)")
}
}
let item2 = DispatchWorkItem {
for i in 0...4{
print("item2 -> \(i) thread: \(Thread.current)")
}
}
let item3 = DispatchWorkItem {
for i in 0...4{
print("item3 -> \(i) thread: \(Thread.current)")
}
}
let item4 = DispatchWorkItem {
for i in 0...4{
print("item4 -> \(i) thread: \(Thread.current)")
}
}
1.Main queue与主线程关联的调度队列,是一种串行队列(Serial),与UI相关的操作必须放在Main queue中执行
- 主队列(串行)追加异步任务 => 按顺序打印
let mainQueue = DispatchQueue.main
mainQueue.async(execute: item1)
mainQueue.async(execute: item2)
mainQueue.async(execute: item3)
mainQueue.async(execute: item4)
//item1 -> 0 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item1 -> 1 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item1 -> 2 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item1 -> 3 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item1 -> 4 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item2 -> 0 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item2 -> 1 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item2 -> 2 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item2 -> 3 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item2 -> 4 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item3 -> 0 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item3 -> 1 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item3 -> 2 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item3 -> 3 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item3 -> 4 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item4 -> 0 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item4 -> 1 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item4 -> 2 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item4 -> 3 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
//item4 -> 4 thread: <NSThread: 0x600000f5c440>{number = 1, name = main}
- 主队列(串行)追加同步任务,会引起死锁
原因分析:
如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。而同步对于任务是立刻执行的,那么当把一个任务放进主队列时,它就会立马执行。
可是主线程现在正在处理 syncMain 方法,任务需要等 syncMain 执行完才能执行。syncMain 执行到第一个任务的时候,又要等第一个任务执行完才能往下执行第二个和第三个任务。这样 syncMain 方法和第一个任务就开始了互相等待,形成了死锁。
func syncMain(){
let mainQueue = DispatchQueue.main
mainQueue.sync(execute: item1)
}
2.Global queue运行在后台线程,是系统内共享的全局队列,是一种并行队列
- 全局队列(并行)追加异步任务 => 随机打印
let globalQueue = DispatchQueue.global()
globalQueue.async(execute: item1)
globalQueue.async(execute: item2)
globalQueue.async(execute: item3)
globalQueue.async(execute: item4)
//item1 -> 0 thread: <NSThread: 0x60000148f200>{number = 7, name = (null)}
//item4 -> 0 thread: <NSThread: 0x600001496440>{number = 8, name = (null)}
//item3 -> 0 thread: <NSThread: 0x6000014846c0>{number = 9, name = (null)}
//item2 -> 0 thread: <NSThread: 0x600001496500>{number = 10, name = (null)}
//item1 -> 1 thread: <NSThread: 0x60000148f200>{number = 7, name = (null)}
//item3 -> 1 thread: <NSThread: 0x6000014846c0>{number = 9, name = (null)}
//item1 -> 2 thread: <NSThread: 0x60000148f200>{number = 7, name = (null)}
//item2 -> 1 thread: <NSThread: 0x600001496500>{number = 10, name = (null)}
//item4 -> 1 thread: <NSThread: 0x600001496440>{number = 8, name = (null)}
//item1 -> 3 thread: <NSThread: 0x60000148f200>{number = 7, name = (null)}
//item4 -> 2 thread: <NSThread: 0x600001496440>{number = 8, name = (null)}
//item1 -> 4 thread: <NSThread: 0x60000148f200>{number = 7, name = (null)}
//item4 -> 3 thread: <NSThread: 0x600001496440>{number = 8, name = (null)}
//item4 -> 4 thread: <NSThread: 0x600001496440>{number = 8, name = (null)}
//item3 -> 2 thread: <NSThread: 0x6000014846c0>{number = 9, name = (null)}
//item3 -> 3 thread: <NSThread: 0x6000014846c0>{number = 9, name = (null)}
//item2 -> 2 thread: <NSThread: 0x600001496500>{number = 10, name = (null)}
//item3 -> 4 thread: <NSThread: 0x6000014846c0>{number = 9, name = (null)}
//item2 -> 3 thread: <NSThread: 0x600001496500>{number = 10, name = (null)}
//item2 -> 4 thread: <NSThread: 0x600001496500>{number = 10, name = (null)}
- 全局队列(并行)追加同步任务,按顺序打印
let globalQueue = DispatchQueue.global()
globalQueue.sync(execute: item1)
globalQueue.sync(execute: item2)
globalQueue.sync(execute: item3)
globalQueue.sync(execute: item4)
//item1 -> 0 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item1 -> 1 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item1 -> 2 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item1 -> 3 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item1 -> 4 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item2 -> 0 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item2 -> 1 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item2 -> 2 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item2 -> 3 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item2 -> 4 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item3 -> 0 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item3 -> 1 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item3 -> 2 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item3 -> 3 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item3 -> 4 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item4 -> 0 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item4 -> 1 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item4 -> 2 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item4 -> 3 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
//item4 -> 4 thread: <NSThread: 0x600001044a80>{number = 1, name = main}
3.Custom queue运行在后台线程,默认是串行队列(Serial),初始化时指定attributes参数为 .concurrent,可以创建成并行队列(Concurrent)
串行队列(Serial)
- 自定义串行队列追加异步任务 => 按顺序打印
let serialQueue = DispatchQueue(label: "serial")
serialQueue.async(execute: item1)
serialQueue.async(execute: item2)
serialQueue.async(execute: item3)
serialQueue.async(execute: item4)
//item1 -> 0 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item1 -> 1 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item1 -> 2 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item1 -> 3 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item1 -> 4 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item2 -> 0 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item2 -> 1 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item2 -> 2 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item2 -> 3 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item2 -> 4 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item3 -> 0 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item3 -> 1 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item3 -> 2 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item3 -> 3 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item3 -> 4 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item4 -> 0 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item4 -> 1 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item4 -> 2 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item4 -> 3 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
//item4 -> 4 thread: <NSThread: 0x600001c8e4c0>{number = 6, name = (null)}
- 自定义串行队列追加同步任务,按顺序打印
let serialQueue = DispatchQueue(label: "serial")
serialQueue.sync(execute: item1)
serialQueue.sync(execute: item2)
serialQueue.sync(execute: item3)
serialQueue.sync(execute: item4)
//item1 -> 0 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item1 -> 1 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item1 -> 2 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item1 -> 3 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item1 -> 4 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item2 -> 0 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item2 -> 1 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item2 -> 2 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item2 -> 3 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item2 -> 4 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item3 -> 0 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item3 -> 1 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item3 -> 2 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item3 -> 3 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item3 -> 4 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item4 -> 0 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item4 -> 1 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item4 -> 2 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item4 -> 3 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
//item4 -> 4 thread: <NSThread: 0x6000004e08c0>{number = 1, name = main}
并行队列(Concurrent)
- 自定义并行队列追加异步任务 => 随机打印
let concurrentQueue = DispatchQueue(label: "concurrent", attributes: .concurrent)
concurrentQueue.async(execute: item1)
concurrentQueue.async(execute: item2)
concurrentQueue.async(execute: item3)
concurrentQueue.async(execute: item4)
//item1 -> 0 thread: <NSThread: 0x6000035c6940>{number = 6, name = (null)}
//item3 -> 0 thread: <NSThread: 0x6000035cc700>{number = 8, name = (null)}
//item2 -> 0 thread: <NSThread: 0x6000035ce0c0>{number = 5, name = (null)}
//item4 -> 0 thread: <NSThread: 0x6000035c1100>{number = 3, name = (null)}
//item1 -> 1 thread: <NSThread: 0x6000035c6940>{number = 6, name = (null)}
//item4 -> 1 thread: <NSThread: 0x6000035c1100>{number = 3, name = (null)}
//item3 -> 1 thread: <NSThread: 0x6000035cc700>{number = 8, name = (null)}
//item2 -> 1 thread: <NSThread: 0x6000035ce0c0>{number = 5, name = (null)}
//item4 -> 2 thread: <NSThread: 0x6000035c1100>{number = 3, name = (null)}
//item3 -> 2 thread: <NSThread: 0x6000035cc700>{number = 8, name = (null)}
//item1 -> 2 thread: <NSThread: 0x6000035c6940>{number = 6, name = (null)}
//item4 -> 3 thread: <NSThread: 0x6000035c1100>{number = 3, name = (null)}
//item2 -> 2 thread: <NSThread: 0x6000035ce0c0>{number = 5, name = (null)}
//item1 -> 3 thread: <NSThread: 0x6000035c6940>{number = 6, name = (null)}
//item3 -> 3 thread: <NSThread: 0x6000035cc700>{number = 8, name = (null)}
//item4 -> 4 thread: <NSThread: 0x6000035c1100>{number = 3, name = (null)}
//item2 -> 3 thread: <NSThread: 0x6000035ce0c0>{number = 5, name = (null)}
//item1 -> 4 thread: <NSThread: 0x6000035c6940>{number = 6, name = (null)}
//item3 -> 4 thread: <NSThread: 0x6000035cc700>{number = 8, name = (null)}
//item2 -> 4 thread: <NSThread: 0x6000035ce0c0>{number = 5, name = (null)}
- 自定义并行队列追加同步任务,按顺序打印
let concurrentQueue = DispatchQueue(label: "concurrent", attributes: .concurrent)
concurrentQueue.sync(execute: item1)
concurrentQueue.sync(execute: item2)
concurrentQueue.sync(execute: item3)
concurrentQueue.sync(execute: item4)
//item1 -> 0 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item1 -> 1 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item1 -> 2 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item1 -> 3 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item1 -> 4 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item2 -> 0 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item2 -> 1 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item2 -> 2 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item2 -> 3 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item2 -> 4 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item3 -> 0 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item3 -> 1 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item3 -> 2 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item3 -> 3 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item3 -> 4 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item4 -> 0 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item4 -> 1 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item4 -> 2 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item4 -> 3 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
//item4 -> 4 thread: <NSThread: 0x600003fa0800>{number = 1, name = main}
三.死锁分析
(1). 主线程中执行, 主队列(串行)+同步任务,会引起死锁.
原因分析:
主队列只能运行在主线程。主队列本身任务与当前同步任务相互等待
自定义串行队列+同步任务,不会死锁
原因分析:
自定义串行队列内本身没有任务,加入同步任务后,按顺序执行,所以不会死锁。
自定义并行队列+同步任务 不会死锁;
自定义并行队列+异步任务,不会死锁
原因分析:
并行队列有能力启动主线程和后台线程(可以启动一个或多个后台线程,部分设备上可以启动多达64个后台线程)。 并行队列遇到同步任务,会自动安排在主线程执行,虽然是并行队列,也只能顺序执行;遇到异步任务,自动安排在后台线程执行,所以不会死锁。
(2). 其他死锁.
自定义串行队列嵌套同步任务,会引起死锁
原因分析:
与主队列+同步任务原因类似,本身已经加入任务1执行(不论是异步还是同步),任务1中又需要执行同步任务2,但是任务2(同步任务)需要等任务1执行完才能执行;任务1又需要等任务2执行完才算执行完任务1.相互等待
let serialQueue = DispatchQueue(label: "serial")
//死锁
serialQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务1
serialQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务2
}
}
//死锁
serialQueue.async {
print("异步执行 thread: \(Thread.current)")//任务1
serialQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务2
}
}
自定义串行队列嵌套异步任务,不会引起死锁
原因分析:
同步嵌套异步:本身已经加入任务1同步执行,任务2是异步任务加入子线程执行,任务3同步执行;
异步嵌套异步:任务1,任务2是异步任务都加入子线程执行
//不会引起死锁
serialQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务1
serialQueue.async {
print("异步执行 thread: \(Thread.current)")//任务2
}
print("同步执行 thread: \(Thread.current)")//任务3
}
//同步执行 thread: <NSThread: 0x60000356c800>{number = 1, name = main}
//同步执行 thread: <NSThread: 0x60000356c800>{number = 1, name = main}
//异步执行 thread: <NSThread: 0x600003569940>{number = 6, name = (null)}
//不会引起死锁
serialQueue.async {
print("异步执行 thread: \(Thread.current)")
serialQueue.async {
print("异步执行 thread: \(Thread.current)")
}
}
//异步执行 thread: <NSThread: 0x600003ff9100>{number = 4, name = (null)}
//异步执行 thread: <NSThread: 0x600003ff9100>{number = 4, name = (null)}
并行队列嵌套同步任务,不会引起死锁
原因分析:异步嵌套同步:任务1,任务2是异步任务都加入子线程执行;
同步嵌套同步:任务1,任务2都在主线程中顺序执行
同步嵌套异步:任务1在主线程中执行,任务2在子线程执行
//自定义并行队列(全局并行队列结果一样)
let concurrentQueue = DispatchQueue(label: "concurrent", attributes: .concurrent)
//不会引起死锁
concurrentQueue.async {
print("异步执行 thread: \(Thread.current)")//任务1
concurrentQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务2
}
}
//异步执行 thread: <NSThread: 0x6000033b5900>{number = 7, name = (null)}
//同步执行 thread: <NSThread: 0x6000033b5900>{number = 7, name = (null)}
//不会引起死锁
concurrentQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务1
concurrentQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务2
}
}
//同步执行 thread: <NSThread: 0x600000064a80>{number = 1, name = main}
//同步执行 thread: <NSThread: 0x600000064a80>{number = 1, name = main}
//不会引起死锁
concurrentQueue.sync {
print("同步执行 thread: \(Thread.current)")//任务1
concurrentQueue.async {
print("异步执行 thread: \(Thread.current)")//任务2
}
}
//同步执行 thread: <NSThread: 0x600000d088c0>{number = 1, name = main}
//异步执行 thread: <NSThread: 0x600000d0d000>{number = 3, name = (null)}
//不会引起死锁
concurrentQueue.async {
print("异步执行 thread: \(Thread.current)")
concurrentQueue.async {
print("异步执行 thread: \(Thread.current)")
}
}
//异步执行 thread: <NSThread: 0x600003f593c0>{number = 5, name = (null)}
//异步执行 thread: <NSThread: 0x600003f52440>{number = 8, name = (null)}
四.实例理解
如何理解同步/异步,串行/并行,这里引用一个例子:
//www.greatytc.com/p/2d57c72016c6
假设现在有 一堆人要穿过一道门禁,这道门禁总共有 10 个入口和一个特殊通道,管理员可以决定同一时间打开几个入口,可以决定同一时间让一个人单独通过还是多个人一起通过。不过默认情况下,管理员只开启一个入口,且一个通道一次只能通过一个人。
这个故事里,人好比是 任务,管理员好比是 系统,入口则代表 线程。
5 个人表示有 5 个任务,10 个入口代表 10 条线程。
串行队列 好比是 5 个人排成一支长队。
并发队列 好比是 5 个人排成多支队伍,比如 2 队,或者 3 队。
同步任务 好比是管理员只开启了一个入口(当前线程)。
异步任务 好比是管理员同时开启了多个入口(当前线程 + 新开的线程)。
主队列 好比是特殊通道(老幼病残孕专用),仅有1个
主队列+异步 可以理解为: 特殊通道只有一个,来了很多正常人,但是无法开启普通通道,队伍只能通过特殊通道依次通过
主队列+同步 可以理解为:特殊通道队伍中的第一名是一个普通人第二名是一个老奶奶,普通人无法通过特殊通道,需要等老幼病残孕优先通过;可是奶奶排在一个普通人的后面 他们无法交换顺序,只能互相等待 ,死锁
(全局/自定义)并行+异步 可以理解为:现在管理员开启了多个入口(比如 3 个入口),5 个人排成了多支队伍(比如 3 支队伍),这样这 5 个人就可以 3 个人同时一起穿过门禁了,随机通过
(全局/自定义)并行+同步 可以理解为:现在管理员只开启了 1 个入口,5 个人排成了多支队伍。虽然这 5 个人排成了多支队伍,但是只开了 1 个入口,这 5 个人虽然都想快点过去,但是 1 个入口一次只能过 1 个人,所以大家就只好一个接一个走过去了,表现的结果就是:顺次通过入口。
自定义串行+异步 可以理解为:现在管理员只开启了 1 个入口,5 个人排成了1支队伍。大家顺次通过入口。
自定义串行+同步 可以理解为:现在管理员只开启了 3个入口,5 个人排成了1支队伍。大家还是顺次通过一个入口。
串行+嵌套同步任务 可以理解为:
串行+同步+嵌套同步: 管理员只开启了一个入口, 2支队伍排在这一个入口,互相谦让,相互等待,死锁
串行+异步+嵌套同步: 管理员开启了多开了1个入口, 2支队伍,都排在了这个入口处处, 互相谦让,相互等待,死锁
串行+嵌套异步任务 可以理解为:
串行+同步/异步+嵌套异步: 管理员开启了一个入口1, 队伍1排在入口1处;又来了一个队伍,管理员开启了入口2,队伍2排在了入口2处.
并行+嵌套同步任务 可以理解为:
并行+同步+嵌套同步: 管理员只开启了默认的一个入口, 队伍1来了排在入口处,又来了一支队伍2,只能排在队伍1后面
并行+异步+嵌套同步: 管理员开启了多开了1个入口, 队伍1来了排在入口处,又来了一支队伍2,只能排在队伍1后面
并行+嵌套异步任务 可以理解为:
并行+同步+嵌套异步: 管理员只开启了默认的一个入口, 队伍1来了排在入口处,又来了一支队伍2,管理员又开启了一个入口
并行+异步+嵌套异步: 队伍1来了,管理员为其开了一个入口; 又来了一支队伍2,管理员又开启了一个入口