Serial vs Concurrent
Serial Queue
- A serial queue requires one task to be completed before proceeding with the next task
public func executeInSerialQueue() {
let serialQueue = DispatchQueue(label: "serialQueue")
serialQueue.async {
for i in 0..<3 {
print("π₯ \(i) in \(#function)")
}
}
serialQueue.async {
for i in 0..<3 {
print("π¦ \(i) in \(#function)")
}
}
}
//π₯ 0 in executeInSerialQueue()
//π₯ 1 in executeInSerialQueue()
//π₯ 2 in executeInSerialQueue()
//π¦ 0 in executeInSerialQueue()
//π¦ 1 in executeInSerialQueue()
//π¦ 2 in executeInSerialQueue()
Concurrent Queue
- Concurrent queue starts the next task even if one task is not completed
public func executeInConcurrentQueue() {
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
for i in 0..<3 {
print("π₯ \(i) in \(#function)")
}
}
concurrentQueue.async {
for i in 0..<3 {
print("π¦ \(i) in \(#function)")
}
}
}
//π¦ 0 in executeInConcurrentQueue()
//π₯ 0 in executeInConcurrentQueue()
//π¦ 1 in executeInConcurrentQueue()
//π₯ 1 in executeInConcurrentQueue()
//π₯ 2 in executeInConcurrentQueue()
//π¦ 2 in executeInConcurrentQueue()
Sync vs Async
- Synchronously starting a task will block the calling thread until the task is finished
- Asynchronously starting a task will directly return on the calling thread without blocking
Sync in a SerialQueue
public func executeSyncInSerialQueue() {
let serialQueue = DispatchQueue(label: "serialQueue")
print("Start")
serialQueue.sync {
for i in 0..<3 {
print("π₯ \(i) in \(#function)")
}
}
serialQueue.sync {
for i in 0..<3 {
print("π¦ \(i) in \(#function)")
}
}
print("End")
}
//Start
//π₯ 0 in executeSyncInSerialQueue()
//π₯ 1 in executeSyncInSerialQueue()
//π₯ 2 in executeSyncInSerialQueue()
//π¦ 0 in executeSyncInSerialQueue()
//π¦ 1 in executeSyncInSerialQueue()
//π¦ 2 in executeSyncInSerialQueue()
//End
Sync in a ConcurrentQueue
public func executeSyncInConcurrentQueue() {
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
print("Start")
concurrentQueue.sync {
for i in 0..<3 {
print("π₯ \(i) in \(#function)")
}
}
concurrentQueue.sync {
for i in 0..<3 {
print("π¦ \(i) in \(#function)")
}
}
print("End")
}
//Start
//π₯ 0 in executeSyncInConcurrentQueue()
//π₯ 1 in executeSyncInConcurrentQueue()
//π₯ 2 in executeSyncInConcurrentQueue()
//π¦ 0 in executeSyncInConcurrentQueue()
//π¦ 1 in executeSyncInConcurrentQueue()
//π¦ 2 in executeSyncInConcurrentQueue()
//End
Async in a SerialQueue
- Since itβs a serial queue, the red task that came in first completes and then the blue task starts
public func executeAsyncInSerialQueue() {
let serialQueue = DispatchQueue(label: "serialQueue")
print("Start")
serialQueue.async {
for i in 0..<3 {
print("π₯ \(i) in \(#function)")
}
}
serialQueue.async {
for i in 0..<3 {
print("π¦ \(i) in \(#function)")
}
}
print("End")
}
//Start
//π₯ 0 in executeAsyncInSerialQueue()
//End
//π₯ 1 in executeAsyncInSerialQueue()
//π₯ 2 in executeAsyncInSerialQueue()
//π¦ 0 in executeAsyncInSerialQueue()
//π¦ 1 in executeAsyncInSerialQueue()
//π¦ 2 in executeAsyncInSerialQueue()
Async in a ConcurrentQueue
public func executeAsyncInConcurrentQueue() {
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)
print("Start")
concurrentQueue.async {
for i in 0..<3 {
print("π₯ \(i) in \(#function)")
}
}
concurrentQueue.async {
for i in 0..<3 {
print("π¦ \(i) in \(#function)")
}
}
print("End")
}
//Start
//End
//π₯ 0 in executeAsyncInConcurrentQueue()
//π¦ 0 in executeAsyncInConcurrentQueue()
//π₯ 1 in executeAsyncInConcurrentQueue()
//π¦ 1 in executeAsyncInConcurrentQueue()
//π₯ 2 in executeAsyncInConcurrentQueue()
//π¦ 2 in executeAsyncInConcurrentQueue()
Reference
Leave a comment