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

输出:

相关推荐
geats人山人海30 分钟前
c# 第九章 record
开发语言·c#
早期的虫儿有鸟吃31 分钟前
vue2--Vuex 模块化
开发语言·前端·javascript
程序员清风36 分钟前
推荐几个我常听的AI播客!
java·后端·面试
浪客川1 小时前
Android的SystemUI的启动流程简析
android·开发语言
JavaGuide1 小时前
Kimi K3 实战:全栈项目、Java 项目改造与 3A 游戏 Demo
后端·ai编程
wuqingshun3141591 小时前
如何理解Spring Boot中的starter?
java·spring boot·后端
AskHarries1 小时前
PayPal 接入避坑
后端
谭光志1 小时前
深入浅出 RAG:用一个可运行的 Demo 讲透完整链路
前端·后端·ai编程
wuqingshun3141591 小时前
SpringBoot是如何实现自动配置的
java·spring boot·后端
-银雾鸢尾-1 小时前
C#中的抽象类与抽象方法
开发语言·c#