Search code examples
iosswiftmultithreadingmacosdispatch-queue

serial Dispatch Queue will use only one thread?


I find that serial queue will use more than one thread to run async code. Here's the test code in playground.

import Foundation  

let q = DispatchQueue(label: "test")  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  
q.async {  
    print("hi \(Thread.current)")  
}  

when I repeatedly execute the playground, there will be output like this sometimes. In my understanding, serial queue should use only one thread, but the log shows it used 2 threads. I am really confused on this. What is the correct behavior?

hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26a467b90>{number = 2, name = (null)}  
hi <NSThread: 0x7fc26b1003e0>{number = 3, name = (null)} 

Solution

  • You are right in saying that serial queue will only use 1 thread at "a" time.

    But will the same thread (NSThread object) execute each block of code that's enqueued into the queue? No.

    To add more clarity to the first statement, I will rephrase it..

    Serial queue will only use 1 thread at a time per block execution. Which means that two threads will never act upon any block of code at any point in time.

    What thread executes the code that's enqueued/dequeued FIFO order from the queue is not guaranteed. But what is guaranteed is that any "one" arbitrary worker thread will perform the action.

    As far as I know, internally, for each block the thread allocation is automatic. "One thread only" does not mean "same thread always".