go: Lock/Mutex Pattern

项目结构:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Lock/Mutex Pattern 互斥锁(Mutex)
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/11 22:00
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry.go
*/
package domain
 
import "sync"
 
// Jewelry 珠宝领域模型(线程安全,互斥锁完全封装)
type Jewelry struct {
    mu    sync.Mutex // 私有锁:外部无法访问,绝对安全
    ID    string
    Name  string
    Stock int
}
 
// NewJewelry 创建珠宝实例
func NewJewelry(id, name string, stock int) *Jewelry {
    return &Jewelry{
        ID:    id,
        Name:  name,
        Stock: stock,
    }
}
 
// Sell 销售:线程安全扣减库存
func (j *Jewelry) Sell(num int) (bool, string) {
    j.mu.Lock()
    defer j.mu.Unlock()
 
    if j.Stock < num {
        return false, "库存不足,无法销售"
    }
    j.Stock -= num
    return true, "销售成功"
}
 
// Replenish 补货:线程安全增加库存
func (j *Jewelry) Replenish(num int) (bool, string) {
    j.mu.Lock()
    defer j.mu.Unlock()
 
    j.Stock += num
    return true, "补货成功"
}
 
// GetStock 线程安全查询库存
func (j *Jewelry) GetStock() int {
    j.mu.Lock()
    defer j.mu.Unlock()
    return j.Stock
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Lock/Mutex Pattern 互斥锁(Mutex)
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/11 22:01
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_repo.go
*/
package repository
 
import (
    "godesginpattern/mutex/domain"
    "sync"
)
 
// JewelryRepository 珠宝存储接口(可扩展MySQL/Redis)
type JewelryRepository interface {
    Save(j *domain.Jewelry)
    GetByID(id string) *domain.Jewelry
}
 
// InMemoryJewelryRepo 内存实现(生产可替换为MySQL)
type InMemoryJewelryRepo struct {
    data map[string]*domain.Jewelry
    mu   sync.Mutex
}
 
func NewInMemoryJewelryRepo() JewelryRepository {
    return &InMemoryJewelryRepo{
        data: make(map[string]*domain.Jewelry),
    }
}
 
func (r *InMemoryJewelryRepo) Save(j *domain.Jewelry) {
    r.mu.Lock()
    defer r.mu.Unlock()
    r.data[j.ID] = j
}
 
func (r *InMemoryJewelryRepo) GetByID(id string) *domain.Jewelry {
    r.mu.Lock()
    defer r.mu.Unlock()
    return r.data[id]
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Lock/Mutex Pattern 互斥锁(Mutex)
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/11 22:02
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_service.go
*/
package service
 
import (
    "godesginpattern/mutex/domain"
    "godesginpattern/mutex/repository"
)
 
type JewelryService struct {
    repo repository.JewelryRepository
}
 
func NewJewelryService(repo repository.JewelryRepository) *JewelryService {
    return &JewelryService{repo: repo}
}
 
// CreateJewelry 创建珠宝
func (s *JewelryService) CreateJewelry(id, name string, stock int) *domain.Jewelry {
    j := domain.NewJewelry(id, name, stock)
    s.repo.Save(j)
    return j
}
 
// SellJewelry 销售珠宝
func (s *JewelryService) SellJewelry(id string, num int) (bool, string) {
    j := s.repo.GetByID(id)
    if j == nil {
        return false, "珠宝不存在"
    }
    success, msg := j.Sell(num)
    s.repo.Save(j)
    return success, msg
}
 
// ReplenishJewelry 补货
func (s *JewelryService) ReplenishJewelry(id string, num int) (bool, string) {
    j := s.repo.GetByID(id)
    if j == nil {
        return false, "珠宝不存在"
    }
    success, msg := j.Replenish(num)
    s.repo.Save(j)
    return success, msg
}
 
// GetStock 查询库存
func (s *JewelryService) GetStock(id string) int {
    j := s.repo.GetByID(id)
    if j == nil {
        return 0
    }
    return j.GetStock()
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Lock/Mutex Pattern 互斥锁(Mutex)
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/11 22:03
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_handler.go
*/
package handler
 
import (
    "fmt"
    "godesginpattern/mutex/service"
    "sync"
)
 
type JewelryHandler struct {
    svc *service.JewelryService
}
 
func NewJewelryHandler(svc *service.JewelryService) *JewelryHandler {
    return &JewelryHandler{svc: svc}
}
 
// RunConcurrentTasks 模拟企业级并发销售/补货
func (h *JewelryHandler) RunConcurrentTasks() {
    var wg sync.WaitGroup
 
    // 并发任务:5个协程同时操作
    wg.Add(5)
 
    go func() {
        defer wg.Done()
        _, msg := h.svc.SellJewelry("D001", 1)
        fmt.Printf("销售员A -> 销售1颗:%s | 库存:%d\n", msg, h.svc.GetStock("D001"))
    }()
 
    go func() {
        defer wg.Done()
        _, msg := h.svc.SellJewelry("D001", 1)
        fmt.Printf("销售员B -> 销售1颗:%s | 库存:%d\n", msg, h.svc.GetStock("D001"))
    }()
 
    go func() {
        defer wg.Done()
        _, msg := h.svc.SellJewelry("D001", 1)
        fmt.Printf("销售员C -> 销售1颗:%s | 库存:%d\n", msg, h.svc.GetStock("D001"))
    }()
 
    go func() {
        defer wg.Done()
        _, msg := h.svc.ReplenishJewelry("D001", 2)
        fmt.Printf("仓  库 -> 补货2颗:%s | 库存:%d\n", msg, h.svc.GetStock("D001"))
    }()
 
    go func() {
        defer wg.Done()
        _, msg := h.svc.SellJewelry("D001", 1)
        fmt.Printf("销售员D -> 销售1颗:%s | 库存:%d\n", msg, h.svc.GetStock("D001"))
    }()
 
    wg.Wait()
    fmt.Println("\n=== 所有并发任务执行完成 ===")
    fmt.Printf("最终库存:%d\n", h.svc.GetStock("D001"))
}

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Lock/Mutex Pattern 互斥锁(Mutex)
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/11 22:07
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : mutexbll.go
Mutex/
├── config/              # 配置定义
├──
│   ├── domain/          # 领域层(核心业务模型 + 锁封装)
│   │   └── jewelry.go   # 珠宝模型 + 互斥锁安全实现
│   ├── repository/      # 数据存储层(持久化)
│   │   └── jewelry_repo.go
│   ├── service/         # 业务逻辑层
│   │   └── jewelry_service.go
│   └── handler/         # 接口/入口层
│       └── jewelry_handler.go
├── cmd/                 # 启动入口
└── go.mod
*/
package bll
 
import (
    "godesginpattern/mutex/handler"
    "godesginpattern/mutex/repository"
    "godesginpattern/mutex/service"
)
 
func MutexMain() {
    // 初始化依赖(DI 依赖注入)
    repo := repository.NewInMemoryJewelryRepo()
    svc := service.NewJewelryService(repo)
    h := handler.NewJewelryHandler(svc)
 
    // 初始化钻石库存:1 颗
    svc.CreateJewelry("D001", "天然钻石", 1)
 
    // 执行并发业务
    h.RunConcurrentTasks()
}

输出:

相关推荐
在繁华处11 小时前
Java从零到熟练(四):面向对象基础
java·开发语言
Unbelievabletobe11 小时前
解决了股票api接口盘后数据更新慢的问题
大数据·开发语言·python
不会C语言的男孩12 小时前
C++ Primer 第2章:变量和基本类型
开发语言·c++
JustHappy13 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本13 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
在繁华处13 小时前
Java从零到熟练(三):流程控制
java·开发语言·python
云泽80814 小时前
C++ 可调用对象通关指南:深度解析 Lambda 表达式、function 包装器与 bind 绑定器
开发语言·c++·算法
星恒随风15 小时前
Python 基础语法详解(一):从表达式、变量到数据类型
开发语言·笔记·python·学习
888CC++15 小时前
java 并发编程
java·开发语言·python
罗超驿16 小时前
18.Web API 实战:元素与表单属性的获取和修改
开发语言·前端·javascript