go:Condition Variable Pattern

项目结构:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Condition Variable  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/10 20:37
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : logger.go
*/
package logger
 
import (
    "log"
    "os"
)
 
type Logger struct {
    *log.Logger
}
 
func NewLogger() *Logger {
    return &Logger{
        Logger: log.New(os.Stdout, "[Jewelry-System] ", log.LstdFlags|log.Lmsgprefix),
    }
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Condition Variable  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/10 20:38
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config
 
// SystemConfig 生产质检系统统一配置(可扩展:DB、MQ、限流等)
type SystemConfig struct {
    BoxCapacity    int // 珠宝箱容量
    WorkerCount    int // 工匠数量
    InspectorCount int // 质检员数量
    ProduceCount   int // 每人生产数量
    CheckCount     int // 每人质检数量
}
 
// DefaultConfig 默认生产配置
func DefaultConfig() *SystemConfig {
    return &SystemConfig{
        BoxCapacity:    2,
        WorkerCount:    2,
        InspectorCount: 2,
        ProduceCount:   3,
        CheckCount:     3,
    }
}
  
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Condition Variable  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/10 20:38
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_box.go
*/
package service
 
import (
    "godesginpattern/conditionvariable/common/logger"
    "godesginpattern/conditionvariable/domain"
    "sync"
)
 
// JewelryBoxService 珠宝箱服务
// 单一职责:仅封装 条件变量 + 并发安全存取
type JewelryBoxService struct {
    mu      sync.Mutex
    cond    *sync.Cond
    storage []*domain.Jewel
    maxCap  int
    logger  *logger.Logger
}
 
// NewJewelryBoxService 创建服务实例
func NewJewelryBoxService(maxCap int, log *logger.Logger) *JewelryBoxService {
    s := &JewelryBoxService{
        maxCap: maxCap,
        logger: log,
    }
    s.cond = sync.NewCond(&s.mu) // 绑定锁
    return s
}
 
// Put 放入珠宝(生产者用)
func (s *JewelryBoxService) Put(j *domain.Jewel) error {
    s.mu.Lock()
    defer s.mu.Unlock()
 
    // 等待:箱子未满
    for len(s.storage) >= s.maxCap {
        s.logger.Printf("珠宝箱已满,工匠[%d]等待 | 容量:%d/%d", j.WorkerID, len(s.storage), s.maxCap)
        s.cond.Wait()
    }
 
    s.storage = append(s.storage, j)
    s.logger.Printf("工匠[%d]放入珠宝:%s | 库存:%d/%d", j.WorkerID, j.ID, len(s.storage), s.maxCap)
 
    s.cond.Signal() // 唤醒一个消费者
    return nil
}
 
// Get 取出珠宝(消费者用)
func (s *JewelryBoxService) Get() (*domain.Jewel, error) {
    s.mu.Lock()
    defer s.mu.Unlock()
 
    // 等待:箱子非空
    for len(s.storage) == 0 {
        s.logger.Println("质检员等待,珠宝箱为空...")
        s.cond.Wait()
    }
 
    jewel := s.storage[0]
    s.storage = s.storage[1:]
    s.logger.Printf("质检员取出珠宝:%s | 剩余库存:%d", jewel.ID, len(s.storage))
 
    s.cond.Signal() // 唤醒一个生产者
    return jewel, nil
}
 
// BroadcastClose 关闭时唤醒所有协程(防止死锁)
func (s *JewelryBoxService) BroadcastClose() {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.cond.Broadcast()
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Condition Variable  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/10 20:39
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : worker.go
*/
package worker
 
import (
    "fmt"
    "godesginpattern/conditionvariable/common/logger"
    "godesginpattern/conditionvariable/domain"
    "godesginpattern/conditionvariable/service"
    "sync"
    "time"
)
 
// JewelWorker 工匠(生产者)
type JewelWorker struct {
    id     int
    total  int
    box    *service.JewelryBoxService
    logger *logger.Logger
    wg     *sync.WaitGroup
}
 
func NewJewelWorker(id int, total int, box *service.JewelryBoxService, log *logger.Logger, wg *sync.WaitGroup) *JewelWorker {
    return &JewelWorker{
        id:     id,
        total:  total,
        box:    box,
        logger: log,
        wg:     wg,
    }
}
 
// Start 启动生产
func (w *JewelWorker) Start() {
    defer w.wg.Done()
 
    for i := 1; i <= w.total; i++ {
        jewelID := fmt.Sprintf("DIAMOND-%d-%d", w.id, i)
        jewel := domain.NewJewel(jewelID, "DIAMOND", w.id)
 
        err := w.box.Put(jewel)
        if err != nil {
            w.logger.Printf("工匠[%d]生产失败: %v", w.id, err)
            continue
        }
 
        time.Sleep(1 * time.Second) // 打磨耗时
    }
 
    w.logger.Printf("✅ 工匠[%d]完成全部生产任务", w.id)
}
 
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Condition Variable  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/10 20:40
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : inspector.go
*/
package worker
 
import (
    "godesginpattern/conditionvariable/common/logger"
    "godesginpattern/conditionvariable/service"
    "sync"
    "time"
)
 
// JewelInspector 质检员(消费者)
type JewelInspector struct {
    id     int
    total  int
    box    *service.JewelryBoxService
    logger *logger.Logger
    wg     *sync.WaitGroup
}
 
func NewJewelInspector(id int, total int, box *service.JewelryBoxService, log *logger.Logger, wg *sync.WaitGroup) *JewelInspector {
    return &JewelInspector{
        id:     id,
        total:  total,
        box:    box,
        logger: log,
        wg:     wg,
    }
}
 
// Start 启动质检
func (i *JewelInspector) Start() {
    defer i.wg.Done()
 
    for n := 0; n < i.total; n++ {
        jewel, err := i.box.Get()
        if err != nil {
            i.logger.Printf("质检员[%d]获取珠宝失败: %v", i.id, err)
            continue
        }
 
        i.logger.Printf("🔍 质检员[%d]完成质检: %s", i.id, jewel.ID)
        time.Sleep(1200 * time.Millisecond)
    }
 
    i.logger.Printf("✅ 质检员[%d]完成全部质检任务", i.id)
}

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Condition Variable  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/10 20:44
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : conditionvariableBll.go
*/
package bll
 
import (
    "godesginpattern/conditionvariable/common/logger"
    "godesginpattern/conditionvariable/config"
    "godesginpattern/conditionvariable/service"
    "godesginpattern/conditionvariable/worker"
    "sync"
)
 
func ConditionVariableMain() {
    // 1. 初始化基础组件
    log := logger.NewLogger()
    cfg := config.DefaultConfig()
    log.Println("=== 珠宝生产质检系统启动 ===")
 
    // 2. 初始化核心服务(条件变量)
    boxService := service.NewJewelryBoxService(cfg.BoxCapacity, log)
 
    // 3. 等待组
    var wg sync.WaitGroup
 
    // 4. 启动所有工匠(生产者)
    log.Printf("启动 %d 名工匠,每人生产 %d 件珠宝", cfg.WorkerCount, cfg.ProduceCount)
    wg.Add(cfg.WorkerCount)
    for i := 1; i <= cfg.WorkerCount; i++ {
        w := worker.NewJewelWorker(i, cfg.ProduceCount, boxService, log, &wg)
        go w.Start()
    }
 
    // 5. 启动所有质检员(消费者)
    log.Printf("启动 %d 名质检员,每人质检 %d 件珠宝", cfg.InspectorCount, cfg.CheckCount)
    wg.Add(cfg.InspectorCount)
    for i := 1; i <= cfg.InspectorCount; i++ {
        ins := worker.NewJewelInspector(i, cfg.CheckCount, boxService, log, &wg)
        go ins.Start()
    }
 
    // 6. 等待全部完成
    wg.Wait()
 
    // 7. 优雅关闭(唤醒所有等待协程)
    boxService.BroadcastClose()
 
    log.Println("=== 系统任务全部完成,正常退出 ===")
}

输出:

相关推荐
时光追逐者1 小时前
一款基于 C# 开发的 Windows 10/11 系统增强工具,精简、优化、定制一站完成!
开发语言·windows·c#·.net
金玉满堂@bj1 小时前
Gin 框架零基础全套入门教程(Go 企业级 Web 开发)
前端·golang·gin
测试员周周1 小时前
【AI测试功能6】功能测试的自动化率:哪些该自动、哪些必须人工——AI测试人机协作决策指南
开发语言·人工智能·python·功能测试·单元测试·自动化·测试用例
绿豆人1 小时前
进入内核-中断开启
开发语言·c#
小杍随笔1 小时前
【Rust桌面革命:Tauri×Dioxus——架构对决、实战拆解与2026选型杀招】
开发语言·架构·rust
计算机安禾1 小时前
【c++面向对象编程】第4篇:类与对象(三):拷贝构造函数与深浅拷贝问题
开发语言·c++·算法
无风听海1 小时前
UseForwardedHeaders 与 UsePathBase:深入理解 ASP.NET Core 代理感知中间件
后端·中间件·asp.net
j_xxx404_1 小时前
Linux共享内存原理与实战:从内核到C++实现|附源码
linux·运维·开发语言·c++·人工智能
金玉满堂@bj1 小时前
Python 后端开发 从零到就业完整教程(2026 企业级完整版)
开发语言·python