package main

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

type Cache struct {
	mu   sync.RWMutex
	data map[string]string
}

func (c *Cache) Get(key string) string {
	c.mu.RLock()
	defer c.mu.RUnlock()
	return c.data[key]
}

func (c *Cache) Set(key, value string) {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.data[key] = value
}

func main() {
	c := &Cache{data: make(map[string]string)}
	c.Set("foo", "bar")

	var wg sync.WaitGroup

	// 多个读 goroutine
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			for j := 0; j < 5; j++ {
				v := c.Get("foo")
				fmt.Printf("reader-%d 第 %d 次读到: %s\n", id, j, v)
				time.Sleep(100 * time.Millisecond)
			}
		}(i)
	}

	// 一个写 goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		time.Sleep(300 * time.Millisecond)
		fmt.Println("writer: 更新 foo -> baz")
		c.Set("foo", "baz")
	}()

	wg.Wait()
}
