In this chapter, we saw the tools that are available in the Go standard package for synchronization. They are located in two packages: sync, which provides high-level tools such as mutexes, and sync/atomic, which executes low-level operations.
First, we saw how to synchronize data using lockers. We saw how to use sync.Mutex to lock a resource regardless of the operation type, and sync.RWMutex to allow for concurrent readings and blocking writes. We should be careful using the second one because writes could be delayed by consecutive readings.
Next, we saw how to keep track of running operations in order to wait for the end of a series of goroutines, using sync.WaitGroup. This acts as a thread-safe counter for current goroutines and makes it possible to put the current goroutine to sleep until it reaches zero, using the Wait method.
Furthermore, we checked...