Concurrent access of maps

suggest change

Maps in Go are not safe for concurrency.

One option to ensure safe concurrent access is to use sync.Mutex or sync.RWMutex and lock around all map reads and writes.

As an example, a simple wrapper around a map that is safe for concurrent use as long as it's done by Get, Set and Add methods:

package main

import (
	"fmt"
	"sync"
)

// ConcurrentMap is a wrapper around map that is safe for concurrent use
type ConcurrentMap struct {
	sync.RWMutex
	m map[string]int
}

// Get gets a value for a key
func (r *ConcurrentMap) Get(key string) int {
	r.RLock()
	defer r.RUnlock()
	return r.m[key]
}

// Set sets a key to a given value
func (r *ConcurrentMap) Set(key string, val int) {
	r.Lock()
	defer r.Unlock()
	r.m[key] = val
}

// Add increases the value under a key by n
func (r *ConcurrentMap) Add(key string, n int) int {
	r.Lock()
	defer r.Unlock()
	r.m[key] += n
	return r.m[key]
}

func main() {
	counter := ConcurrentMap{m: make(map[string]int)}

	n := counter.Add("some_key", 2)
	fmt.Printf("Final value is: %d\n", n)
}
Final value is: 2

sync.RWMutex can be faster because it allows multiple readers. On the downside you have to be more careful to ensure you're not writing under RLock. The performance difference with sync.Mutex will be negligible unless there's a high-contention on the lock or the locks are held for a long time.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents