Go
Beginner
1 min read
Goroutines with sync.WaitGroup and sync.Mutex
Example
package main
import (
"fmt"
"sync"
)
// SafeCounter is safe for concurrent use.
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
defer c.mu.Unlock()
c.v[key]++
}
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
defer c.mu.Unlock()
return c.v[key]
}
// ReadCache uses RWMutex for read-heavy workloads.
type ReadCache struct {
mu sync.RWMutex
data map[string]string
}
func (rc *ReadCache) Set(k, v string) {
rc.mu.Lock()
defer rc.mu.Unlock()
rc.data[k] = v
}
func (rc *ReadCache) Get(k string) (string, bool) {
rc.mu.RLock()
defer rc.mu.RUnlock()
v, ok := rc.data[k]
return v, ok
}
func main() {
c := SafeCounter{v: make(map[string]int)}
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
c.Inc("hits")
}()
}
wg.Wait()
fmt.Println("hits:", c.Value("hits")) // 100
cache := ReadCache{data: make(map[string]string)}
cache.Set("lang", "Go")
if v, ok := cache.Get("lang"); ok {
fmt.Println("cached:", v)
}
}