/*:#localized(key: "WrappingUp")
 # Wrapping up

 GCD's whole promise is that you stop managing threads and start handing
 closures to **queues**. Get comfortable with which queue does what, and with
 the single decision of `async` versus `sync`, and the rest is detail. Most
 of the sharp edges live around `sync`, so read the takeaways below before
 you reach for it.

 * **GCD manages threads for you.** You hand closures to **queues**; you
 don't create threads yourself.
 * Three queues: **main** (UI, serial), **global** (shared background,
 concurrent), and **custom** (`DispatchQueue(label:)`, serial by default).
 Reach for a custom queue to guard state or name a line of work; for "get
 this off main," `global()` is simpler.
 * **`async`** schedules work and returns immediately; **`sync`** blocks the
 current thread until the work finishes. You almost always want `async`.
 * **Serial** queues guarantee order and no overlap; **concurrent** queues
 run tasks in parallel and finish in any order. Never depend on that finish
 order.
 * The core pattern is **work on a background queue, then hop back to
 `DispatchQueue.main.async` to update the UI**: touching UI off the main
 thread is undefined behavior.
 * **QoS** tells GCD how urgent work is; pick it by asking whether someone is
 waiting, and whether they're watching.
 * **Pitfall:** `main.sync` from the main thread **deadlocks**. Never do it.

 ---
 
 ## Up next

 **[Groups and semaphores](Groups%20and%20Semaphores.playgroundchapter/Overview)** is next: how to wait for a whole batch of
 dispatched work to finish, and how to limit how many tasks touch a resource
 at once.

 [Previous](@previous)  |  page 9 of 9
 */
