/*:#localized(key: "ConcurrencyVsParallelism")
 # Concurrency vs. parallelism

 These two words get used interchangeably. They are not the same, and the difference
 is worth getting right early.

 * **Concurrency** is *dealing with* many things at once: a way of **structuring**
 your program so tasks can make progress independently, interleaving on whatever
 processors are available.
 * **Parallelism** is *doing* many things at the literal same instant: tasks
 running simultaneously on multiple CPU cores.

 The coffee bar makes it concrete. **Concurrent, one barista:** the barista starts
 your pour-over, and *while it drips* takes the next person's order and starts their
 espresso. One worker, but no one waits idly. **Parallel, two baristas:** two people
 literally pulling two shots at the same moment.

 Concurrency is about *structure*; parallelism is about *execution*. Crucially,
 **concurrency helps even on a single core**, because most "slow" work isn't the CPU
 straining, it's *waiting*: for the network, the disk, a timer. A waiting task can
 step aside and let another run.
 */
//#-editable-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

// Two independent "orders." Each waits (network, disk...) then reports.
// We simulate waiting with a background queue and a sleep.
let counter = DispatchQueue(label: "order-counter", attributes: .concurrent)

counter.async {
    Thread.sleep(forTimeInterval: 1.0)   // waiting for a slow pour-over
    print("Pour-over ready")
}

counter.async {
    Thread.sleep(forTimeInterval: 0.5)   // a quicker espresso
    print("Espresso ready")
}

print("Both orders taken; barista is free to keep working")

// When both orders finish, stop the page. A `.barrier` block on a concurrent
// queue runs only after every earlier block has completed. More on barriers
// in the GCD Fundamentals chapter.
counter.async(flags: .barrier) {
    DispatchQueue.main.async {
        PlaygroundPage.current.finishExecution()
    }
}
//#-end-editable-code
/*:#localized(key: "ConcurrencyVsParallelism-2")
 Run the code. `Both orders taken...` prints first. Then **espresso** appears before
 **pour-over**, even though it was ordered second: it simply finished its wait
 sooner. Don't worry about the `DispatchQueue` syntax yet, that's all of the next
 chapter. Right now, just notice the *shape*: work moved off the main line, and the
 counter stayed open.

 * callout(Try it): Swap the two waits (pour-over `0.2`, espresso `0.8`) and predict
 which line prints first now.

 [Previous](@previous)  |  page 3 of 5  |  [Next: Responsiveness First](@next)
 */
