go: Monitor Pattern

项目结构:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:09
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config
 
const (
    BufferCapacity   = 3   // 珠宝缓冲区容量
    ProducerCount    = 2   // 工匠(生产者)数量
    ConsumerCount    = 1   // 质检员(消费者)数量
    ProducePerWorker = 5   // 每个工匠生产数量
    ProduceDelayMs   = 300 // 生产模拟耗时
    ConsumeDelayMs   = 500 // 质检模拟耗时
)
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:09
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry.go
*/
package domain
 
// Jewelry 珠宝实体(行业核心对象)
type Jewelry struct {
    ID       int
    Type     string // 钻戒/项链/手镯
    Material string // 材质
}
 
// 生产类型常量
const (
    JewelryTypeRing     = "钻戒"
    JewelryTypeNecklace = "黄金项链"
    MaterialRing        = "钻石+铂金"
    MaterialNecklace    = "足金999"
)
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:10
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : monitor.go
*/
package service
 
import (
    "godesginpattern/monitor/domain"
)
 
// JewelryMonitor 监控器接口(监控模式标准接口)
// 职责单一:只定义生产/消费行为,不关心实现
type JewelryMonitor interface {
    // Produce 生产珠宝(生产者)
    Produce(jewelryType, material string) error
    // Consume 消费珠宝(消费者)
    Consume() (*domain.Jewelry, error)
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:11
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : jewelry_monitor.go
*/
package impl
 
import (
    "errors"
    "godesginpattern/monitor/domain"
    "godesginpattern/monitor/service"
    "sync"
)
 
// jewelryMonitor 监控器实现(私有结构体,外部只能通过接口访问)
type jewelryMonitor struct {
    mutex    sync.Mutex
    cond     *sync.Cond
    buffer   []*domain.Jewelry
    capacity int
    seq      int
}
 
// NewJewelryMonitor 创建监控器实例(依赖注入)
func NewJewelryMonitor(capacity int) service.JewelryMonitor {
    jm := &jewelryMonitor{
        capacity: capacity,
    }
    // 条件变量绑定互斥锁(监控模式核心)
    jm.cond = sync.NewCond(&jm.mutex)
    return jm
}
 
// ==================== 生产者实现 ====================
func (jm *jewelryMonitor) Produce(jewelryType, material string) error {
    jm.mutex.Lock()
    defer jm.mutex.Unlock()
 
    // 必须用 for 循环:防止虚假唤醒(企业级规范)
    for len(jm.buffer) == jm.capacity {
        jm.cond.Wait()
    }
 
    // 生产
    jm.seq++
    j := &domain.Jewelry{
        ID:       jm.seq,
        Type:     jewelryType,
        Material: material,
    }
    jm.buffer = append(jm.buffer, j)
 
    // 通知消费者
    jm.cond.Signal()
    return nil
}
 
// ==================== 消费者实现 ====================
func (jm *jewelryMonitor) Consume() (*domain.Jewelry, error) {
    jm.mutex.Lock()
    defer jm.mutex.Unlock()
 
    for len(jm.buffer) == 0 {
        jm.cond.Wait()
    }
 
    // 消费
    if len(jm.buffer) == 0 {
        return nil, errors.New("buffer empty")
    }
 
    j := jm.buffer[0]
    jm.buffer = jm.buffer[1:]
 
    // 通知生产者
    jm.cond.Signal()
    return j, nil
}
  
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:12
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : producer.go
*/
package worker
 
import (
    "godesginpattern/monitor/config"
    "godesginpattern/monitor/domain"
    "godesginpattern/monitor/service"
    "log"
    "time"
)
 
// StartProducer 启动生产者协程
func StartProducer(
    monitor service.JewelryMonitor,
    workerID int,
    produceCount int,
) {
    for i := 0; i < produceCount; i++ {
        // 按工匠ID分配生产类型
        jType, material := domain.JewelryTypeRing, domain.MaterialRing
        if workerID == 2 {
            jType, material = domain.JewelryTypeNecklace, domain.MaterialNecklace
        }
 
        _ = monitor.Produce(jType, material)
        log.Printf("[工匠%d] 生产完成: %s | %s", workerID, jType, material)
 
        time.Sleep(time.Millisecond * time.Duration(config.ProduceDelayMs))
    }
 
    log.Printf("[工匠%d] ✅ 全部生产任务完成", workerID)
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:12
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : consumer.go
*/
package worker
 
import (
    "godesginpattern/monitor/config"
    "godesginpattern/monitor/service"
    "log"
    "time"
)
 
// StartConsumer 启动消费者协程
func StartConsumer(
    monitor service.JewelryMonitor,
    totalConsume int,
) {
    for i := 0; i < totalConsume; i++ {
        j, _ := monitor.Consume()
        log.Printf("[质检员] 质检完成: ID=%d | %s | %s", j.ID, j.Type, j.Material)
 
        time.Sleep(time.Millisecond * time.Duration(config.ConsumeDelayMs))
    }
 
    log.Println("[质检员] ✅ 全部质检任务完成")
}
  

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:监控模式 Monitor 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/17 20:13
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : monitorbll.go
 
monitor/
├── config/              # 配置定义
├── domain/              # 领域模型(核心业务实体)
├── service/             # 业务服务(监控模式核心实现)
│   ├── monitor.go       # 监控器接口定义
│   └── impl/
│       └── jewelry_monitor.go  # 互斥锁+条件变量 实现
├── worker/              # 生产者/消费者工作协程
│   ├── producer.go       # 监控器接口定义
│   └── consumer.go
├── cmd/                 # 项目启动入口
│   └── main.go
├── go.mod
└── go.sum
*/
package bll
 
import (
    "godesginpattern/monitor/config"
    "godesginpattern/monitor/service/impl"
    "godesginpattern/monitor/worker"
    "log"
    "sync"
)
 
func MonitorMain() {
    log.Println("=== 珠宝生产-质检系统 启动 ===")
 
    // 1. 创建监控器(依赖注入)
    monitor := impl.NewJewelryMonitor(config.BufferCapacity)
 
    // 2. 等待组
    var wg sync.WaitGroup
 
    // 3. 启动生产者
    totalProduce := 0
    wg.Add(config.ProducerCount)
    for i := 1; i <= config.ProducerCount; i++ {
        go func(id int) {
            defer wg.Done()
            worker.StartProducer(monitor, id, config.ProducePerWorker)
        }(i)
        totalProduce += config.ProducePerWorker
    }
 
    // 4. 启动消费者
    wg.Add(1)
    go func() {
        defer wg.Done()
        worker.StartConsumer(monitor, totalProduce)
    }()
 
    // 5. 等待全部完成
    wg.Wait()
 
    log.Println("=== 🎉 珠宝生产-质检全流程完成 ===")
}
  

输出:

相关推荐
雪度娃娃2 小时前
行为型设计模式——命令模式
c++·设计模式·命令模式
我能坚持多久2 小时前
STL详解——list的介绍以及功能展示
开发语言·c++
郭龙_Jack2 小时前
Java的虚拟线程 VS Go语言的goroutine
java·golang
Brilliantwxx2 小时前
【C++】 继承与多态(上)
开发语言·c++·笔记·算法
ch.ju2 小时前
Java程序设计(第3版)第四章——静态部分
java·开发语言
ZHOUPUYU2 小时前
PHP 开发实战:从零搭建一个高性能的 RESTful API 服务
运维·开发语言·后端·html·php
不负岁月无痕2 小时前
STL -- C++ string 类 模拟实现
java·开发语言·c++
身如柳絮随风扬2 小时前
除了 JWT,你还用过哪些认证方案?Spring Security 中如何集成 JWT?
java·后端·spring
Anastasiozzzz2 小时前
万字深度实战!AI Agent 接入万物的底层密码:MCP 协议传输机制与开发指南(下篇)
java·开发语言·数据库·人工智能·ai·架构