go: Read-Write Lock Pattern

项目结构:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 读写锁模式 Read-Write Lock  Pattern
# 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/18 20:32
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry.go
*/
package model
 
import "sync"
 
// Jewelry 珠宝核心实体
type Jewelry struct {
    ID    string  `json:"id"`
    Name  string  `json:"name"`
    Type  string  `json:"type"` // 钻石/黄金/铂金
    Price float64 `json:"price"`
    Stock int     `json:"stock"`
}
 
// JewelryRepository 数据层接口(面向接口编程,可扩展存储:MySQL/Redis)
type JewelryRepository interface {
    GetJewelry(id string) (*Jewelry, error)
    ListJewelry() ([]*Jewelry, error)
    UpdateJewelry(j *Jewelry) error
}
 
// jewelryMemoryRepo 内存存储(使用读写锁保证并发安全)
type jewelryMemoryRepo struct {
    data map[string]*Jewelry
    mu   sync.RWMutex // 核心:读写锁
}
  
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 读写锁模式 Read-Write Lock  Pattern
# 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/18 20:34
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_service.go
*/
package service
 
import "godesginpattern/readwritelock/model"
 
type JewelryService struct {
    repo model.JewelryRepository
}
 
func NewJewelryService(repo model.JewelryRepository) *JewelryService {
    return &JewelryService{repo: repo}
}
 
func (s *JewelryService) GetJewelryInfo(id string) (*model.Jewelry, error) {
    return s.repo.GetJewelry(id)
}
 
func (s *JewelryService) ListAllJewelry() ([]*model.Jewelry, error) {
    return s.repo.ListJewelry()
}
 
func (s *JewelryService) UpdateJewelryPriceStock(id string, price float64, stock int) error {
    j, err := s.repo.GetJewelry(id)
    if err != nil {
        return err
    }
    j.Price = price
    j.Stock = stock
    return s.repo.UpdateJewelry(j)
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 读写锁模式 Read-Write Lock  Pattern
# 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/18 20:35
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_controller.go
*/
package controller
 
import (
    "fmt"
    //"godesginpattern/readwritelock/model"
    "godesginpattern/readwritelock/service"
)
 
type JewelryController struct {
    service *service.JewelryService
}
 
func NewJewelryController(svc *service.JewelryService) *JewelryController {
    return &JewelryController{service: svc}
}
 
func (c *JewelryController) ListJewelry() {
    list, err := c.service.ListAllJewelry()
    if err != nil {
        fmt.Println("查询失败:", err)
        return
    }
    fmt.Println("======= 珠宝列表 =======")
    for _, j := range list {
        fmt.Printf("ID:%s | %s | 价格:%.2f | 库存:%d\n",
            j.ID, j.Name, j.Price, j.Stock)
    }
}
 
func (c *JewelryController) UpdateJewelry(id string, price float64, stock int) {
    err := c.service.UpdateJewelryPriceStock(id, price, stock)
    if err != nil {
        fmt.Println("更新失败:", err)
        return
    }
    fmt.Printf("✅ 珠宝[%s] 更新成功\n", id)
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 读写锁模式 Read-Write Lock  Pattern
# 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/18 20:34
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_repo.go
*/
package repository
 
import (
    "errors"
    "godesginpattern/readwritelock/model"
    "sync"
)
 
// jewelryMemoryRepo 实现了 model.JewelryRepository 接口
// 
type jewelryMemoryRepo struct {
    data map[string]*model.Jewelry
    mu   sync.RWMutex // 读写锁
}
 
// NewJewelryMemoryRepo 创建内存存储实例
func NewJewelryMemoryRepo() model.JewelryRepository {
    return &jewelryMemoryRepo{
        data: make(map[string]*model.Jewelry),
    }
}
 
// ==================== 读操作(并行) ====================
func (r *jewelryMemoryRepo) GetJewelry(id string) (*model.Jewelry, error) {
    r.mu.RLock()
    defer r.mu.RUnlock()
 
    j, ok := r.data[id]
    if !ok {
        return nil, errors.New("珠宝不存在")
    }
    return j, nil
}
 
func (r *jewelryMemoryRepo) ListJewelry() ([]*model.Jewelry, error) {
    r.mu.RLock()
    defer r.mu.RUnlock()
 
    list := make([]*model.Jewelry, 0, len(r.data))
    for _, j := range r.data {
        list = append(list, j)
    }
    return list, nil
}
 
// ==================== 写操作(独占) ====================
func (r *jewelryMemoryRepo) UpdateJewelry(j *model.Jewelry) error {
    r.mu.Lock()
    defer r.mu.Unlock()
 
    r.data[j.ID] = j
    return nil
}

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 读写锁模式 Read-Write Lock  Pattern
# 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/18 20:41
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : readwritelockbll.go
 
ReadWriteLock/
├── go.mod
├── main.go # 入口
│   ├── model/
│   │   └── jewelry.go # 只定义实体 + 接口
│   ├── repository/
│   │   └── jewelry_repo.go # 实现读写锁存储(真正放 jewelryMemoryRepo)
│   ├── service/
│   │   └── jewelry_service.go
│   └── controller/
│       └── jewelry_controller.go
*/
package bll
 
import (
    "fmt"
    "godesginpattern/readwritelock/controller"
    "godesginpattern/readwritelock/model"
    "godesginpattern/readwritelock/repository"
    "godesginpattern/readwritelock/service"
    "sync"
    "time"
)
 
func ReadWriteLockMain() {
    // 依赖注入
    repo := repository.NewJewelryMemoryRepo()
    svc := service.NewJewelryService(repo)
    ctl := controller.NewJewelryController(svc)
 
    // 初始化测试数据
    _ = repo.UpdateJewelry(&model.Jewelry{
        ID:    "J001",
        Name:  "一克拉钻石项链",
        Type:  "钻石",
        Price: 59999.99,
        Stock: 10,
    })
 
    var wg sync.WaitGroup
 
    fmt.Println("======== 高并发并行读(客户查看珠宝)========")
    for i := 1; i <= 10; i++ {
        wg.Add(1)
        go func(num int) {
            defer wg.Done()
            ctl.ListJewelry()
            time.Sleep(200 * time.Millisecond)
        }(i)
    }
    wg.Wait()
 
    fmt.Println("\n======== 独占写(商家修改价格)========")
    wg.Add(1)
    go func() {
        defer wg.Done()
        ctl.UpdateJewelry("J001", 49999.99, 8)
    }()
    wg.Wait()
 
    fmt.Println("\n======== 再次并行读 ========")
    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go func(num int) {
            defer wg.Done()
            ctl.ListJewelry()
        }(i)
    }
 
    wg.Wait()
    fmt.Println("\n🎉 珠宝系统运行完成")
}

输出:

相关推荐
葫芦和十三1 小时前
图解 MongoDB 19|Oplog:复制的真正载体,不是文档是操作
后端·mongodb·agent
葫芦和十三1 小时前
图解 MongoDB 20|复制延迟与 catch up:Secondary 为什么跟不上
后端·mongodb·agent
IT_陈寒6 小时前
SpringBoot自动配置的坑,我的API突然就404了
前端·人工智能·后端
ServBay7 小时前
为什么说 MCP 是 2026 年开发者必须掌握的黄金协议?
后端·mcp
程序员夏洛7 小时前
Spring Boot 多模块项目中 IDEA 提示 Cannot resolve symbol 的一次排查记录
后端
子兮曰7 小时前
OpenMontage 深度解剖:你的 AI 编程助手,其实是个视频工作室
前端·后端·ai编程
子兮曰7 小时前
前端工具链的「Rust 化」:一场没有赢家的军备竞赛?
前端·后端·rust
爱勇宝8 小时前
从 Ctrl+CV 到 Enter:程序员正在失去什么
前端·后端·程序员
码事漫谈9 小时前
EdgeOne Makers + WorkBuddy:零基础也能快速搭建可上线的 AI 智能体(附图文教程)
后端