How to implement efficient locks on Map of Map

Viewed 36

I'm trying to modify values of a map of maps.

Following code shows fatal error: concurrent map read and map write unless I lock whole Map (using defer in method Map.Add in line 17).

My question is, how can I implement it correctly to effectively make use of goroutines concurrency and do not turn my asynchronous code to some synchronous code?

package main

import (
    "fmt"
    "sync"
    "time"
)

type Map struct {
    mutex sync.Mutex
    item  map[int]*Item
}

func (m *Map) Add(key int) {
    m.mutex.Lock()
    m.item[key] = &Item{value: make(map[int]int)}
    defer m.mutex.Unlock()
    
    for j := 0; j < 100; j++ {
        go m.item[key].Inc(j)
    }
}

type Item struct {
    mutex sync.Mutex
    value  map[int]int
}

func (m *Item) Inc(key int) {
    m.mutex.Lock()
    m.value[key]++
    m.mutex.Unlock()
}

func (m *Item) Value(key int) int {
    m.mutex.Lock()
    defer m.mutex.Unlock()
    return m.value[key]
}



func main() {
    m := Map{item: make(map[int]*Item)}

    for i := 0; i < 100; i++ {
        go m.Add(i)
    }

    time.Sleep(time.Second)
    fmt.Println(m.item[1])
}
0 Answers
Related