This article will explain what are synchronizations and list the synchronization techniques supported by Go.
Often, at run time, in a concurrent program, a value will be accessed by multiple goroutines. For such circumstances, we must control which goroutines can acquire the ownership of the value at a given time. Otherwise, data races may happen and the integrity of the value will not get guaranteed.
We use all kinds of data synchronization techniques to transfer or guard value ownerships between goroutines to avoid data races in current programs.Here, more specifically, about the ownership of a value,
(In fact, more precisely, to avoid data races, what we care about is the ownerships of some memmory segments. At run time, a value may occupy multiple memmory segments. We might not care about the ownerships of all the memmory segments occupied by a value in writing a piece of concurrent code. But, for explanation simplicity, we will still use the "ownerships of values" wording in descriptions throughout Go 101 articles.)
We can also do synchronizations by making use of network and file IO. But such techniques are very inefficient whthin a single program process. Generally, they are used for inter-process and distributed synchronizations. Go 101 will not cover such techniques.
To understand these synchronization techniques better, it is recommended to know the memory order guarantees in Go.
The data synchronization techniques in Go will not prevent you from writing improper concurrent code. However the techniques provided by Go can help you write correct concurrent code easily. And the unique channel features make concurrent programming flexible and enjoyable.