Part 1 , Part 2 , Part 3 , Part 4 , Part 5
Buffered Channels in Go are similar to unbuffered channels, but they allow a writer to write without blocking if the channel is not full, which can be useful for concurrent data processing where the reader needs to be decoupled. However, using buffered channels can consume memory even when the buffer is empty, so they should be used with care. Nevertheless, they can be more efficient than unbuffered channels if the necessary amount of memory is known beforehand.
Playground: https://go.dev/play/p/RhcdgNNPNmb
package main
import (
"fmt"
"sync"
)
func main() {
iMax, jMax := 10, 10
// create a buffered channel to store the products of two numbers
// the channel has the exact capacity of the number of products
// that will be written to it
productChan := make(chan int, iMax*jMax)
wg := sync.WaitGroup{}
// use many goroutines to compute the product of two numbers
for i := 0; i < iMax; i++ {
for j := 0; j < jMax; j++ {
copyI, copyJ := i, j
wg.Add(1)
go func() {
defer wg.Done()
// send the product to an unbuffered channel
productChan <- copyI * copyJ
}()
}
}
// wait here and allow all the go routines to finish
// their work and write to the buffered channel
// this is only possible because the channel is buffered
// and has the exact capacity of the number of products
// that will be written to it
wg.Wait()
// close the channel to signal that no more products
// will be written to it
// the close signal will appended to the end of the channel
// and the channel will stay open until all the products
// are read from the channel
close(productChan)
// read the products from the channel
// until the channel is closed
for product := range productChan {
fmt.Println(product)
}
fmt.Println("Done")
}