Sobes.tech
Junior — Senior

Data races in an unsafe counter

livecode

Task condition

The example implements a simple counter that is intended to be used in a multithreaded environment, but access to the shared structure occurs without any synchronization. You need to understand what errors occur during concurrent method calls and how to properly protect the internal state from race conditions.

 type SafeCounter struct {
    values map[string]int
 }

 func (ctr *SafeCounter) Inc(key string) {
    ctr.values[key]++
 }

 func (ctr *SafeCounter) Value(key string) int {
    return ctr.values[key]
 }

 func main() {
    counter := SafeCounter{values: make(map[string]int)}
    for i := 0; i < 1000; i++ {
        go counter.Inc("somekey")
    }

    time.Sleep(time.Second)
    fmt.Println(counter.Value("somekey"))
}