golang mutex and RWMutex example
Here is an example of how to use Mutex
package main
import (
"fmt"
"sync"
)
type Counter struct {
mu sync.Mutex
value int
}
func (c *Counter) Inc() {
c.mu.Lock() // lock
defer c.mu.Unlock() // unlock at function exit
c.value++
}
func (c *Counter) Value() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.value
}
func main() {
var wg sync.WaitGroup
c := Counter{}
// 5 goroutines incrementing 1000 times each
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
c.Inc()
}
}()
}
wg.Wait()
fmt.Println("Final count:", c.Value()) // should be 5000
}
Another example how to use RWMutex - whereby RLock it is capable of allowing goroutine to perform multiple read operations as long as there's no active writer.
package main
import (
"fmt"
"sync"
"time"
)
type SafeCounter struct {
mu sync.RWMutex
m map[string]int
}
func (c *SafeCounter) Inc(key string) {
c.mu.Lock() // exclusive write lock
defer c.mu.Unlock()
c.m[key]++
}
func (c *SafeCounter) Get(key string) int {
c.mu.RLock() // shared read lock
defer c.mu.RUnlock()
return c.m[key]
}
func main() {
c := SafeCounter{m: make(map[string]int)}
// Start multiple readers and writers
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 0; j < 5; j++ {
c.Inc("hello")
time.Sleep(10 * time.Millisecond)
}
}(i)
}
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
for j := 0; j < 5; j++ {
val := c.Get("hello")
fmt.Printf("Reader %d sees %d\n", id, val)
time.Sleep(10 * time.Millisecond)
}
}(i)
}
wg.Wait()
fmt.Println("Final count:", c.Get("hello"))
}
Comments