Difference between dispatch_async and dispatch_sync on serial queue?

旧时模样 提交于 2019-11-26 21:09:35

Yes. Using serial queue ensure the serial execution of tasks. The only difference is that dispatch_sync only return after the block is finished whereas dispatch_async return after it is added to the queue and may not finished.

for this code

dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");

It may print 2413 or 2143 or 1234 but 1 always before 3

for this code

dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");

it always print 1234


Note: For first code, it won't print 1324. Because printf("3") is dispatched after printf("2") is executed. And a task can only be executed after it is dispatched.


The execution time of the tasks doesn't change anything. This code always print 12

dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });

What may happened is

  • Thread 1: dispatch_async a time consuming task (task 1) to serial queue
  • Thread 2: start executing task 1
  • Thread 1: dispatch_async another task (task 2) to serial queue
  • Thread 2: task 1 finished. start executing task 2
  • Thread 2: task 2 finished.

and you always see 12

Dave DeLong

The difference between dispatch_sync and dispatch_async is simple.

In both of your examples, TASK 1 will always execute before TASK 2 because it was dispatched before it.

In the dispatch_sync example, however, you won't dispatch TASK 2 until after TASK 1 has been dispatched and executed. This is called "blocking". Your code waits (or "blocks") until the task executes.

In the dispatch_async example, your code will not wait for execution to complete. Both blocks will dispatch (and be enqueued) to the queue and the rest of your code will continue executing on that thread. Then at some point in the future, (depending on what else has been dispatched to your queue), Task 1 will execute and then Task 2 will execute.

It is all related to main queue. There are 4 permutations.

i) Serial queue, dispatch async : Here the tasks will execute one after the other, but the main thread(effect on UI) will not wait for return

ii) Serial queue, dispatch sync: Here the tasks will execute one after the other, but the main thread(effect on UI) will show lag

iii) Concurrent queue, dispatch async : Here the tasks will execute in parallel and the main thread(effect on UI ) will not wait for return and will be smooth.

iv) Concurrent queue, dispatch sync : Here the tasks will execute in parallel, but the main thread(effect on UI) will show lag

Your choice of concurrent or serial queue depends on if you need an output from a previous task for the next one. If you depend on the previous task, adopt the serial queue else take concurrent queue.

And lastly this is a way of penetrating back to the main thread when we are done with our business :

DispatchQueue.main.async {
     // Do something here
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!