一、GCD常用的隊(duì)列和函數(shù)
串行隊(duì)列: 讓任務(wù)一個(gè)接著一個(gè)執(zhí)行(一個(gè)任務(wù))
let serialQue = DispatchQueue(label: “”)并發(fā)隊(duì)列: 可以讓多個(gè)任務(wù)并發(fā)同時(shí)執(zhí)行(自動(dòng)開啟多個(gè)線程),但需注意的是并發(fā)功能只有在.async函數(shù)才有效。
let concurrenceQueue = DispatchQueue(label: "", qos: .default, attributes: DispatchQueue.Attributes.concurrent)全局并行隊(duì)列 :
let globalQueue = DispatchQueue.global()主隊(duì)列:
let mainQueUe = DispatchQueue.main
異步的方式執(zhí)行任務(wù)
serialQue.async {}
同步的方式執(zhí)行任務(wù)
serialQue.sync { }

使用sync函數(shù)往當(dāng)前串行隊(duì)列中添加任務(wù),會(huì)卡住當(dāng)前的串行隊(duì)列(產(chǎn)生死鎖)常見下面2個(gè)例子。
例子1:
let serialQue = DispatchQueue(label: “”)
serialQue.sync {
serialQue.sync{
print("同步任務(wù)”)
}
}
例子2:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
DispatchQueue.main.sync {
print("同步任務(wù)")
}
}
}
二、DispatchWorkItem
DispatchWorkItem 到底是個(gè)什么呢?通俗的來說,DispatchWorkItem 就是 GCD 里面常說的一段待執(zhí)行的任務(wù),更直白一點(diǎn),它本質(zhì)只是一個(gè)等待執(zhí)行的代碼塊而已,可以在任意一個(gè)隊(duì)列上被調(diào)用。
let workItem = DispatchWorkItem {
print("執(zhí)行任務(wù)一")
}
DispatchQueue.global().async(execute: workItem)
workItem.notify(queue: DispatchQueue.main) {
print("任務(wù)執(zhí)行完回到主隊(duì)列刷新UI")
}
workItem.cancel()
-
workItem的閉包里面是封裝的任務(wù) - notify是執(zhí)行完任務(wù)在某個(gè)隊(duì)列做一些事情,這里直接回歸到主隊(duì)列。
- cancel取消任務(wù)
三、延遲執(zhí)行
let workItem = DispatchWorkItem {
print("延遲10s執(zhí)行任務(wù)")
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now()+10, execute: workItem)
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now()+3) {
print("延遲3s執(zhí)行任務(wù)")
}
四、柵欄函數(shù)
let concurrenceQueue = DispatchQueue(label: "", qos: .default, attributes: DispatchQueue.Attributes.concurrent)
concurrenceQueue.async {
sleep(10)
print("任務(wù)一")
}
concurrenceQueue.async {
sleep(20)
print("任務(wù)二")
}
concurrenceQueue.async(flags: .barrier) {
print("柵欄任務(wù)結(jié)束")
}
concurrenceQueue.async {
print("任務(wù)三")
}
這個(gè)例子就是任務(wù)一、任務(wù)二、任務(wù)三的任務(wù)中添加了柵欄,會(huì)導(dǎo)致任務(wù)三被隔離,任務(wù)、任務(wù)二任務(wù)完成之后才會(huì)去執(zhí)行任務(wù)三
五、隊(duì)列組
let concurrenceQueue = DispatchQueue(label: "", qos: .default, attributes: DispatchQueue.Attributes.concurrent)
let group = DispatchGroup()
group.enter()
group.enter()
concurrenceQueue.async(group: group) {
print("任務(wù)一")
group.leave()
};
concurrenceQueue.async(group: group) {
print("任務(wù)二")
group.leave()
};
group.notify(queue: DispatchQueue.main) {
print("所有任務(wù)結(jié)束")
}
六、信號(hào)量
1、控制線程的最大并發(fā)數(shù)量
class ViewController: UIViewController {
var semaphore:DispatchSemaphore?
override func viewDidLoad() {
super.viewDidLoad()
semaphore = DispatchSemaphore(value: 3)
for _ in 0...10 {
let thread = Thread(target: self, selector: #selector(test), object: nil)
thread.start()
}
}
@objc func test(){
semaphore?.wait()
sleep(10)
print("測(cè)試")
semaphore?.signal()
}
}
2、保證線程安全(控制線程的最大并發(fā)數(shù)量為1)
class ViewController: UIViewController {
var semaphore:DispatchSemaphore?
var array:[Any] = Array()
override func viewDidLoad() {
super.viewDidLoad()
semaphore = DispatchSemaphore(value: 1)
for _ in 0...10000 {
let thread = Thread(target: self, selector: #selector(test), object: nil)
thread.start()
}
}
@objc func test(){
semaphore?.wait()
array.append(2)
print("測(cè)試")
semaphore?.signal()
}
}
3、線程同步
var semaphore:DispatchSemaphore?
var array:[Any] = Array()
override func viewDidLoad() {
super.viewDidLoad()
semaphore = DispatchSemaphore(value: 0)
self.request1()
semaphore?.wait()
self.request2()
}
func request1(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
self.semaphore?.signal()
print("request1")
}
}
func request2(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
print("request2")
}
}
}
這樣就保證了request1執(zhí)行完后才能執(zhí)行request2
4、多線程依賴
假如request1、request2請(qǐng)求完之后,再請(qǐng)求request3我們就可以這樣
class ViewController: UIViewController {
var semaphore:DispatchSemaphore?
var group:DispatchGroup?
var array:[Any] = Array()
override func viewDidLoad() {
super.viewDidLoad()
let group = DispatchGroup()
self.group = group
let semophore = DispatchSemaphore.init(value: 0)
self.semaphore = semophore
let queue = DispatchQueue.global()
queue.async(group: group, execute: {
self.request1()
semophore.wait()
})
queue.async(group: group, execute: {
self.request2()
semophore.wait()
})
group.notify(queue: queue) {
self.request3()
}
}
func request1(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
DispatchQueue.main.async {
self.semaphore?.signal()
print("request1")
}
}
}
func request2(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
DispatchQueue.main.async {
self.semaphore?.signal()
print("request2")
}
}
}
func request3(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
DispatchQueue.main.async {
print("request3")
}
}
}
}
或者這樣
class ViewController: UIViewController {
var semaphore:DispatchSemaphore?
var group:DispatchGroup?
var array:[Any] = Array()
override func viewDidLoad() {
super.viewDidLoad()
let group = DispatchGroup()
self.group = group
let semophore = DispatchSemaphore.init(value: 0)
self.semaphore = semophore
let queue = DispatchQueue.global()
queue.async(group: group, execute: {
self.request1()
})
queue.async(group: group, execute: {
self.request2()
})
group.notify(queue: queue) {
semophore.wait()
semophore.wait()
self.request3()
}
}
func request1(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
DispatchQueue.main.async {
self.semaphore?.signal()
print("request1")
}
}
}
func request2(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
DispatchQueue.main.async {
self.semaphore?.signal()
print("request2")
}
}
}
func request3(){
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + Double.random(in: 0...5)
) {
DispatchQueue.main.async {
print("request3")
}
}
}
}
七、多線程開發(fā)-once
dispatch_once在Swift中已經(jīng)被廢棄,取而代之可以用類型屬性或者全局變量\常量。
fileprivate let inittask2:Void = {
print("inittask2")
}()
class Student{
static let initTask1:Void = {
print("inittask1")
}()
}