Threads are heavy, expensive to create, and limited—only so many threads can be created—So when a thread is blocked it is, in a way, being wasted. Because of this, Kotlin offers what is called Suspendable Computations; these are computations that can suspend their execution without blocking the thread of execution. So instead of, for example, blocking thread X to wait for an operation to be made in a thread Y, it's possible to suspend the code that has to wait and use thread X for other computations in the meantime.
Furthermore, Kotlin offers great primitives like channels, actors, and mutual exclusions, which provide mechanisms to communicate and synchronize concurrent code effectively without having to block a thread.
Chapter 6, Channels – Share Memory by Communicating, Chapters 7, Thread Confinement, Actors, and Mutexes, and Chapter 8, Testing Concurrent Code, will focus on the correct usage of channels, actors, mutexes, and more to correctly communicate and synchronize your concurrent code.