go Lock Sleep

package main

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

// Goods 结构体,包含一个 map[int]int 用于存储商品编号和库存数量,以及一个互斥锁
type Goods struct {
	v map[int]int   // 商品编号到库存数量的映射
	m sync.Mutex    // 互斥锁,保证并发安全
}

// Inc 方法,增加指定商品编号的库存数量
func (g *Goods) Inc(key int, num int) {
	g.m.Lock() // 加锁,保证并发安全
	defer g.m.Unlock()
	fmt.Printf("库存数量增加,已加锁\n")
	g.v[key]++ // 增加库存
	fmt.Printf("库存数量增加完毕,解锁\n")
}

// Value 方法,获取指定商品编号的库存数量
func (g *Goods) Value(key int) int {
	g.m.Lock() // 加锁,保证并发安全
	defer g.m.Unlock()
	fmt.Println("库存值上锁\n")
	return g.v[key]
}

func main() {
	// 初始化 Goods 结构体
	g := Goods{
		v: make(map[int]int), // 商品编号到库存数量的映射
	}

	// 并发增加编号为 666 的商品库存
	for i := 0; i < 10; i++ {
		go g.Inc(666, i)
	}

	// 等待所有 goroutine 执行完毕
	time.Sleep(1 * time.Second)

	// 获取并打印编号为 666 的商品库存
	fmt.Println(g.Value(666))
}

详细解释

1. 结构体定义

  • Goods 结构体包含:
    • v map[int]int:用数字(如商品编号)作为 key,库存数量为 value。
    • m sync.Mutex:互斥锁,保证并发操作 map 时的安全。

2. Inc 方法

  • Inc(key int, num int):增加指定编号商品的库存。
  • g.m.Lock()defer g.m.Unlock():加锁和解锁,防止并发写入时数据冲突。
  • g.v[key]++:将指定编号商品的库存加一。

3. Value 方法

  • Value(key int) int:获取指定编号商品的库存。
  • 同样加锁,防止并发读写冲突。

4. main 函数

  • 初始化 Goods,map 的 key 变为数字。
  • 启动 10 个 goroutine 并发增加编号为 666 的商品库存。
  • time.Sleep(1 * time.Second):等待所有 goroutine 执行完毕(实际生产建议用 sync.WaitGroup)。
  • 打印编号为 666 的商品库存。

你可能感兴趣的:(golang)