Reputation: 285
I know the difference between the two kinds.
For async tasks, next task will run after the current one began, which means tasks will be dispatched to multiple threads if there are threads available.
For sync tasks, next task will run after the current one finished.
How could main thread run async tasks since it only has one thread?
It's confusing to me.
Thanks in advance.
Upvotes: 4
Views: 859
Reputation: 438467
For async tasks, next task will run after the current one began, which means tasks will be dispatched to multiple threads if there are threads available.
Not quite. To dispatch asynchronously only means that the current thread will not wait for the dispatched code to finish. It has absolutely nothing to do with whether that destination queue is serial or concurrent.
For sync tasks, next task will run after the current one finished.
Again, not quite. To dispatch synchronously only means that the current thread will wait for the dispatched code to finish execution.
Whether the dispatched code runs concurrently with respect to other items previously dispatched to that queue is dictated by the queue type (i.e. serial or concurrent), not whether we dispatched synchronously or asynchronously.
How could main thread run async tasks since it only has one thread?
As is likely obvious now, the “asynchronous” vs “synchronous” is not a characteristic of the task being dispatched, but rather only dictates whether the thread from which you are dispatching should wait or not.
So, consider some code that dispatches code asynchronously back to the main thread:
let task = URLSession.dataTask(with: request) { data, _, _ in
let results = ... // on `URLSession` background serial queue, only populate local variables
DispatchQueue.main.async {
self.objects = results // dispatch model updates back to main queue
self.tableView.reloadData() // also update UI from main queue
}
}
task.resume()
In the above example, we’re dispatching the model and UI updates to the main queue because we’re on the URLSession
background queue (which happens to be a serial queue, too). And we dispatch it asynchronously because there is no reason for the serial queue of the URLSession
to wait for the dispatched code to finish. We could have dispatched it synchronously, but why would we bother blocking the URLSession
queue, even if only for a few extra milliseconds.
Upvotes: 4
Reputation: 115083
Your definitions of asynchronous and synchronous aren't quite right.
In Grand Central Dispatch you consider queues, not threads. A queue is either a serial dispatch queue or a concurrent dispatch queue.
A serial dispatch queue can run one task at a time and tasks are dispatched one after the other (serially).
A concurrent dispatch queue can run several tasks simultaneously on multiple threads.
Tasks execute on threads and Grand Central Dispatch takes care of assigning tasks to threads for you.
The main queue is a special serial dispatch queue that only assigns tasks to the main thread. Other queues can assign tasks to any available thread, including the main thread.
Now, for synchronous versus asynchronous dispatch, the difference is whether the dispatch blocks the current thread until the dispatched task is complete (synchronous) or queues the task without blocking the current thread (asynchronous).
When you dispatch asynchronously onto the main queue, you are providing a unit of work that Grand Central Dispatch will assign to the main thread at some future point, but your code continues executing without waiting for that dispatched item to complete.
You can dispatch asynchronous tasks to the main queue while running on the main queue quite happily, since the dispatched task will execute later, when the main queue is ready for a task.
What you can't do is dispatch synchronously onto the main queue from the main queue (or more generally, dispatch synchronously onto any serial dispatch queue from that same queue) since you will create a deadlock.
Dispatching synchronously blocks the current thread/queue until the dispatched item is complete. On a serial dispatch queue the dispatched item can't execute since the dispatching queue is blocked.
Upvotes: 7