Channels are the coroutine dual of concurrent blocking queues. A blocking queue is a data type that provides operations so that you can add or remove elements from an internal buffer. These operations will block when they cannot be completed.
Typically, these operations are called put, which adds elements to the buffer—and blocks when the queue is full (unblocks when space is freed by a consumer removing an element)—and take, which removes elements from the queue—and blocks when the queue is empty (unblocks when the queue is populated by a producer adding an element).
Channels offer the same basic functionality but rather than using blocking operations, they use suspendable functions, which allows producer-consumer style patterns but with the efficiency of coroutines. In Kotlin, the add and remove functions of a channel are called send and receive...