多线程的理解

一.概念

串行(Serial)

多个任务放在串行队列里执行,只能按顺序依次运行,前一个运行完成,下一个才能开始运行;前一个没运行完,后一个只能排队等着。以此类推,直到所有任务都运行完成。

串行队列.png

并发(Concurrency)

多个任务放在并行队列里执行,可以同时运行.

并行队列.png

串行和并行描述的是 任务和任务之间 的执行方式;执行顺序不同,以及开启线程数不同。

并发和并行

  • 并发:(Concurrency)
    在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行(不断切换)。
  • 并行:(Parallelism)
    在操作系统中,一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的。

单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)
而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)

并发和并行微观示意图.png

同步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}
image.png

三.死锁分析

(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)}
image.png

四.实例理解

如何理解同步/异步,串行/并行,这里引用一个例子:

//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,管理员又开启了一个入口

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容