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🎉 珠宝系统运行完成")
}

输出:

相关推荐
神仙别闹7 小时前
基于 C++ 实现(控制台)学生成绩管理系统
开发语言·c++
伞伞悦读8 小时前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
GreenTea8 小时前
GrokBot 核心成员 Lauren Tan:每月交付 2000 个 PR 的人,是怎么用 AI 的
前端·后端·架构
码事漫谈8 小时前
FDE:一个缩写,两种命运
后端
xiaofeiyang1508 小时前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
名字还没想好☜9 小时前
Go context.AfterFunc 实战(Go 1.21):context 一取消就自动跑清理,告别手写 goroutine 监听 Done
后端·golang·go
web守墓人9 小时前
【goed/ui】自定义组件设计思想篇
linux·windows·ui·golang
明月_清风10 小时前
为什么最近开始关注 JEV?几个实战案例告诉你答案
人工智能·后端
2601_9669496510 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
m0_7345717611 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g