Thread Safety in Golang
--
Goroutines are awesome. They are arguably the best solution for concurrency out there. However, your applications can get very unpredictable, and cause nasty bugs if you don’t use goroutines properly. One of the most important things to keep in mind is that if your goroutines are going to modify the state of any value stored in a memory address, you need to make them thread safe ( keep in mind that goroutines are actually just cheap threads) .
What exactly do I mean by this. Let me explain through an example:
Here is a very simple example. Say we have an application that is tracking the population of countries in real time. The population of a country is dynamic, babies get born all the time, and sadly some people pass away all the time.
The USA is a huge country, which consists of 50 states. So, for the sake of my example, this updatePopulation
will simulate a single call to some Census Agency of every state. Since we're in a cheerful mood (and also because I need it to prove my point), we'll only register the newborns and not the departed.
Since we want this app to truly be a real-time tracker, we don’t want to make synchronous API calls, we want to make them concurrently by using goroutines, hence the go
in front of the updatePopulation
function call.
That should do it, right? Let’s see the result:
New population of USA is 32001199
New population of USA is 32001030
New population of USA is 32001206
New population of USA is 32001176
New population of USA is 32000957
New population of USA is 32001005
Hmm.. If we are only tracking newborns, and not tracking the deceased… how come our population is actually lower in the last line than the first line?
Well, it’s because we haven’t implemented thread safety. Our various goroutines are accessing the same memory address without any respect for order. It’s like those old people at the supermarket that pretend they don’t see the line.