創(chuàng)建DispatchQueue
// 與當(dāng)前進程的主線程相關(guān)聯(lián)的調(diào)度隊列, 即主隊列滩届。
class var main: DispatchQueue { get }
// 返回一個系統(tǒng)全局隊列
class func global(qos: DispatchQoS.QoSClass = .default) -> DispatchQueue
/**
* 創(chuàng)建一個派發(fā)隊列才菠。
* label:隊列的唯一標(biāo)識渠欺。
* qos :決定了系統(tǒng)安排任務(wù)執(zhí)行的優(yōu)先級虱颗。
* attributes : 執(zhí)行隊列的執(zhí)行方式高蜂,串行還是并行聪黎。
* autoreleaseFrequency : 指示隊列自動釋放對象的頻率的常量。
* target : 計劃執(zhí)行blocks的目標(biāo)隊列备恤。如果希望系統(tǒng)提供適合當(dāng)前對象的隊列稿饰,請指定DISPATCH_TARGET_QUEUE_DEFAULT。
*/
convenience init(label: String, qos: DispatchQoS = .unspecified, attributes: DispatchQueue.Attributes = [], autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit, target: DispatchQueue? = nil)
// 獲取主隊列
let mainQueue = DispatchQueue.main
// 獲取全局隊列
let globalQueue = DispatchQueue.global()
// 自定義一個并行隊列
let customConcurrentQueue = DispatchQueue(label: "com.queue.concurrent", qos: .unspecified, attributes: [.concurrent], autoreleaseFrequency: .inherit, target: nil)
// 自定義一個串行隊列露泊,attributes不賦值即是串行喉镰。
let serialConcurrentQueue = DispatchQueue(label: "com.queue.serial", qos: .unspecified, attributes: [], autoreleaseFrequency: .inherit, target: nil)
print("mainQueue is \(mainQueue)")
print("globalQueue is \(globalQueue)")
print("customConcurrentQueue is \(customConcurrentQueue)")
print("serialConcurrentQueue is \(serialConcurrentQueue)")
輸出結(jié)果:
mainQueue is <OS_dispatch_queue_main: com.apple.main-thread>
globalQueue is <OS_dispatch_queue_global: com.apple.root.default-qos>
customConcurrentQueue is <OS_dispatch_queue_concurrent: com.queue.concurrent>
serialConcurrentQueue is <OS_dispatch_queue_serial: com.queue.serial>
//異步執(zhí)行任務(wù)主要有以下這些方法:
//wallDeadline 和 deadline,當(dāng)系統(tǒng)睡眠后,wallDeadline會繼續(xù)惭笑,但是deadline會被掛起侣姆。例如:設(shè)置參數(shù)為60分鐘,當(dāng)系統(tǒng)睡眠50分鐘脖咐,wallDeadline會在系統(tǒng)醒來之后10分鐘執(zhí)行铺敌,而deadline會在系統(tǒng)醒來之后60分鐘執(zhí)行。
// 立即執(zhí)行派發(fā)的任務(wù)屁擅,并立即return偿凭。
func async(execute: DispatchWorkItem)
// 在指定的時間執(zhí)行派發(fā)的任務(wù),并立即return派歌。
func asyncAfter(deadline: DispatchTime, execute: DispatchWorkItem)
// 在指定的時間執(zhí)行派發(fā)的任務(wù)的block弯囊,并立即return。
func asyncAfter(deadline: DispatchTime, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping @convention(block) () -> Void)
// 在指定的時間后執(zhí)行派發(fā)的任務(wù)胶果,并立即return匾嘱。
func asyncAfter(wallDeadline: DispatchWallTime, execute: DispatchWorkItem)
// 在指定的時間后執(zhí)行派發(fā)的任務(wù)的block,并立即return早抠。
func asyncAfter(wallDeadline: DispatchWallTime, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @escaping @convention(block) () -> Void)
同步任務(wù)+串行隊列
(沒有開啟新線程霎烙,串行執(zhí)行任務(wù),當(dāng)前線程(主線程)中運行)
let queue1 = DispatchQueue(label: "queue")
print("begin")
queue1.sync {
print("線程1運行")
}
queue1.sync {
print("線程2運行")
}
print("end")
/*
begin
線程1運行
線程2運行
end
*/
同步任務(wù)+并發(fā)隊列
(沒有開啟新線程蕊连,串行執(zhí)行任務(wù)悬垃,當(dāng)前線程(主線程)中運行)
let queue2 = DispatchQueue(label: "queue1", attributes: .concurrent)
print("begin")
queue2.sync {
print("線程1運行")
}
queue2.sync {
print("線程2運行")
}
print("end")
/*
begin
線程1運行
線程2運行
end
*/
異步任務(wù)+串行隊列
(開啟1條新線程,串行執(zhí)行任務(wù)甘苍,開啟1條新線程中運行)
let queue3 = DispatchQueue(label: "queue")
print("begin")
queue3.async {
print("線程1運行")
}
queue3.async {
print("線程2運行")
}
print("end")
/*
begin
end
線程1運行
線程2運行
*/
異步任務(wù)+并發(fā)隊列
(開啟2條新線程尝蠕,并發(fā)執(zhí)行任務(wù),2條新線程中運行)
let queue4 = DispatchQueue(label: "queue1", attributes: .concurrent)
print("begin")
queue4.async {
print("線程1運行")
}
queue4.async {
print("線程2運行")
}
print("end")
/*
begin
end
線程1運行
線程2運行
*/
項目中用到的
//1.延遲執(zhí)行
//DispatchTime.now() 獲取當(dāng)前時間
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
//需要進行的操作
}
//2.異步進行耗時操作,主線程進行用戶交互以及刷新UI的操作
//開啟一個全局的異步隊列
DispatchQueue.global().async {
//耗時操作
DispatchQueue.main.async {
//進行UI刷新和用戶交互
}
}
//3.處理多數(shù)據(jù)請求,所有請求完畢進行UI更新
//創(chuàng)建工作組
let workingGroup = DispatchGroup()
//創(chuàng)建隊列
let workingQueue = DispatchQueue(label: "requestData", attributes: .concurrent)
//第一個網(wǎng)絡(luò)請求
workingGroup.enter()
workingQueue.async {
//進行數(shù)據(jù)請求1
workingGroup.leave()
}
//第二個網(wǎng)絡(luò)請求
workingGroup.enter()
workingQueue.async {
//進行數(shù)據(jù)請求2
workingGroup.leave()
}
//請求完畢
workingGroup.notify(queue: .main) {
//進行UI的更新
}
信號量
相當(dāng)于一把鎖载庭,信號量為0則阻塞線程看彼,大于0則不會阻塞廊佩。則我們通過改變信號量的值,來控制是否阻塞線程靖榕,從而達到線程同步
// 創(chuàng)建一個信號标锄,value:信號量
let semaphore = DispatchSemaphore.init(value: <#T##Int#>)
// 某個信號進行等待或等待降低信號量,只有當(dāng)信號量大于0時才會停止等待,繼續(xù)向下執(zhí)行
semaphore.wait()
// 使某個信號的信號量+1
semaphore.signal()
func semaphore_demo() {
let queue = DispatchQueue.global()
//創(chuàng)建信號量 值為1 意思是最大并發(fā)數(shù)為1序矩,任務(wù)只能一個接一個執(zhí)行
let semaphore = DispatchSemaphore.init(value: 1)
//此時信號量為1鸯绿,無需等待,向下執(zhí)行 信號量 1->0
semaphore.wait()
queue.asyncAfter(deadline: .now() + 4) {
print("1111")
//延遲4秒后輸出1111簸淀,釋放信號量瓶蝴,信號量 從0->1
semaphore.signal()
}
//延遲4秒輸出1111后,此時信號量為1租幕,繼續(xù)向下執(zhí)行 同上操作舷手。。劲绪。
semaphore.wait()
queue.asyncAfter(deadline: .now() + 10) {
print("2222")
semaphore.signal()
}
semaphore.wait()
queue.asyncAfter(deadline: .now() + 2) {
print("3333")
semaphore.signal()
}
semaphore.wait()
queue.asyncAfter(deadline: .now() + 1) {
print("4444")
semaphore.signal()
}
semaphore.wait()
queue.asyncAfter(deadline: .now() + 6) {
print("5555")
semaphore.signal()
}
semaphore.wait()
print("任務(wù)全部完成")
semaphore.signal()
}
輸出
1111
2222
3333
4444
5555
任務(wù)全部完成