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()
}

输出:

相关推荐
counterxing1 小时前
AI Agent 做长任务,问题到底 出在哪?
前端·后端·ai编程
知识分享小能手1 小时前
R语言入门学习教程,从入门到精通,R语言日期和时间序列(6)
开发语言·学习·r语言
aiopencode2 小时前
iOS开发中Xcode安装不完整问题解决方案与配置指南
后端·ios
该用户已不存在2 小时前
别让 Claude Code 果奔,用 Claude Code MCP 与 Skills 打造自动化开发(Part 2)
后端·ai编程·claude
叼烟扛炮2 小时前
C++ 知识点18 内部类
开发语言·c++·算法·内部类
TAN-90°-2 小时前
Java 3——getter和setter super()关键字
java·开发语言
wand codemonkey2 小时前
(二十七)Maven(依赖)【安装】+【项目结构】
java·开发语言·maven
linda公馆2 小时前
Maven项目报错:java:错误:不支持发行版本 5
java·开发语言·maven
Ulyanov2 小时前
《从质点到位姿:基于Python与PyVista的导弹制导控制全栈仿真》: 可视化革命——基于 PyVista 的 3D 战场构建与实时渲染
开发语言·python·算法·3d·系统仿真