最近常问的一道面试题,自己也整理一下。
题目:4个任务ABCD,先做A, 再同时做B,C,最后做D
print("start")
//Execute 4 tasks A, B, C, D on order: A -> B,C -> D
let workA = DispatchWorkItem {
print(Date(), "+++ A started")
Thread.sleep(forTimeInterval: 2)
print(Date(), "--- A finished")
}
let workB = DispatchWorkItem {
print(Date(), "+++ B started")
Thread.sleep(forTimeInterval: 4)
print(Date(), "--- B finished")
}
let workC = DispatchWorkItem {
print(Date(), "+++ C started")
Thread.sleep(forTimeInterval: 2)
print(Date(), "--- C finished")
}
let workD = DispatchWorkItem {
print(Date(), "+++ D started")
Thread.sleep(forTimeInterval: 4)
print(Date(), "--- D finished")
}
let concurrent = DispatchQueue(label: "concurrent", qos: .utility, attributes: .concurrent)
let group = DispatchGroup()
//#1.1 Use DispatchQueue barrier
print("Use DispatchQueue barrier")
concurrent.sync(execute: workA)
concurrent.async(execute: workB)
concurrent.async(execute: workC)
concurrent.sync(flags:.barrier) {
workD.perform()
}
//#1.2 Use DispatchWorkItem barrier
print("Use DispatchWorkItem barrier")
let barrierWorkD = DispatchWorkItem(flags:.barrier) {
workD.perform()
}
concurrent.sync(execute: workA)
concurrent.async(execute: workB)
concurrent.async(execute: workC)
concurrent.sync(execute: barrierWorkD)
//#2.1 Use DispatchGroup
print("Use DispatchGroup")
workA.perform()
concurrent.async(group: group, execute: workB)
concurrent.async(group: group, execute: workC)
group.wait()
workD.perform()
//#2.2 Use DispatchGroup enter leave
print("Use DispatchGroup enter leave")
workA.perform()
group.enter()
concurrent.async {
workB.perform()
group.leave()
}
group.enter()
concurrent.async {
workC.perform()
group.leave()
}
group.wait()
workD.perform()
//#3. Use DispatchSemaphore
print("Use DispatchSemaphore")
let semaphore = DispatchSemaphore(value: 0)
workA.perform()
concurrent.async {
workB.perform()
semaphore.signal()
}
concurrent.async {
workC.perform()
semaphore.signal()
}
semaphore.wait()
semaphore.wait()
workD.perform()
//#4. Use OperationQueue
print("Use OperationQueue")
let queue = OperationQueue()
let boA = BlockOperation {
workA.perform()
}
let boB = BlockOperation {
workB.perform()
}
boB.addDependency(boA)
let boC = BlockOperation {
workC.perform()
}
boC.addDependency(boA)
let boD = BlockOperation {
workD.perform()
}
boD.addDependency(boB)
boD.addDependency(boC)
queue.addOperations([boA, boB, boC, boD], waitUntilFinished: true)
print("end")