In Go, we can think of channels as tunnels that allow goroutines to communicate and synchronize with each
other by passing data.
There are two types of channels in Go: unbuffered and buffered channels. Let's see what they are and how they
differ from each other.
Unbuffered Channel
An unbuffered channel in Go is a channel with no capacity to store any data. Any value
sent to an unbuffered channel must be immediately handed off to a receiving goroutine, meaning the send and receive operation must
occur simultaneously.
Send operation blocks until another goroutine is ready to receive the value.
Receive operation blocks until there is a value available to receive.
Let's see an example:
Here, ch <- 1 operation blocks until the receiving end is ready to receive the
value. Similarly, ch <- 2 blocks until the receiving end is ready to receive the
second value.
Buffered Channel
A buffered channel in Go is a channel that has a specified capacity to hold a set number of values.
This means a buffered channel can temporarily store values without requiring an immediate receiver. Unlike
unbuffered channels, send and receive operations on buffered channels don't have to happen at the same time as
long as the buffer isn't full.
Send operation blocks when the buffer is full.
Receive operation blocks only when the buffer is empty.
Let's see an example:
Here, sending 1 and 2 to the channel doesn't block because the buffer has enough capacity for both values.
To handle the blocking of ch <-3 when the buffer is full, we can introduce a goroutine to continuously
receive values from the channel, which frees up space in the buffer and prevents it from blocking. Here's how: