Using maps in goroutines

Im trying to understand more about race conditions, and i made this program that basically just increments a value in a map.
Concurrent access for maps in goroutines should be done using some kind of synchronisation, thats why i used mutex here.
The final answer of the value in the map should be 100, since the program was synchronised with waitGroups and mutexes, but thats not what we get.
Is there something im missing?

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

type mapData struct {
	sync.RWMutex
	data map[string]int
}

func (m *mapData) read(key string) int {
	m.RLock()
	defer m.RUnlock()
	return m.data[key]
}

func (m *mapData) write(key string) {
	m.Lock()
	m.data[key]++
	m.Unlock()
	wg.Done()
}

func main() {
	m := mapData{}
	m.data = make(map[string]int)

	for i := 1; i <= 100; i++ {
		wg.Add(1)
		go m.write("a")
	}

	fmt.Println(m.read("a"))

	wg.Wait()
}
1 Like

The final answer is 100. You just have to be patient and Wait!

wg.Wait()
fmt.Println("final", m.read("a"))
package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

type mapData struct {
	sync.RWMutex
	data map[string]int
}

func (m *mapData) read(key string) int {
	m.RLock()
	defer m.RUnlock()
	return m.data[key]
}

func (m *mapData) write(key string) {
	m.Lock()
	m.data[key]++
	m.Unlock()
	wg.Done()
}

func main() {
	m := mapData{}
	m.data = make(map[string]int)

	for i := 1; i <= 100; i++ {
		wg.Add(1)
		go m.write("a")
	}

	fmt.Println(m.read("a"))

	wg.Wait()

	fmt.Println("final", m.read("a"))
}

https://play.golang.org/p/cp_4NPjENUI

final 100

2 Likes

Awesome way to put it. Thanks :wink: