























/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer 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/6/19 19:31
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : config.go
*/
package config
// 配置层
const (
QueueMaxSize = 5
MaxProduceCount = 10 // 最大生产数量,达到后自动停止
ProducerThreads = 1
ProcessThreads = 2
QualityThreads = 1
WarehouseThreads = 1
SaleThreads = 2
// 模拟耗时(最小,最大)秒
TimeRaw = 1.0
TimeRawMax = 3.0
TimeProcess = 2.0
TimeProcessMax = 4.0
TimeQuality = 1.0
TimeQualityMax = 2.0
TimeWarehouse = 0.5
TimeWarehouseMax = 1.0
TimeSale = 1.0
TimeSaleMax = 3.0
)
var (
RawMaterials = []string{"黄金原料", "钻石原石", "翡翠原石", "铂金原料"}
QualityLevels = []string{"S级(顶级)", "A级(优质)", "B级(普通)"}
)
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer 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/6/19 19:32
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : utils.go
*/
package utils
import (
"fmt"
"math/rand"
"time"
)
// 工具层(日志 + 耗时模拟)
func init() {
rand.Seed(time.Now().UnixNano())
}
// Info 统一日志输出(和 Python 格式一致)
func Info(tag, msg string) {
now := time.Now().Format("2006-01-02 15:04:05")
fmt.Printf("%s | INFO | %s | %s\n", now, tag, msg)
}
// Sleep 模拟业务耗时
func Sleep(min, max float64) {
delta := max - min
s := min + rand.Float64()*delta
time.Sleep(time.Duration(s*1000) * time.Millisecond)
}
// RandString 生成8位ID
func RandString() string {
chars := "0123456789abcdef"
res := make([]byte, 8)
for i := 0; i < 8; i++ {
res[i] = chars[rand.Intn(len(chars))]
}
return string(res)
}
// RandomChoice 随机选择
func RandomChoice(list []string) string {
return list[rand.Intn(len(list))]
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer 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/6/19 19:32
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : jewelry.go
*/
package models
// 数据模型 实体
type JewelryStage string
const (
Raw JewelryStage = "原料"
Processed JewelryStage = "成品"
Qualified JewelryStage = "已分级"
Salable JewelryStage = "可销售"
)
type Jewelry struct {
ID string
Material string
Stage JewelryStage
QualityLevel string
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer 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/6/19 19:31
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : manager.go
*/
package core
import (
"godesginpattern/producerconsumer/models"
"sync"
)
// 核心队列 & 停止管理器
// QueueManager 全局队列单例
type QueueManager struct {
RawQueue chan *models.Jewelry
ProcessQueue chan *models.Jewelry
QualityQueue chan *models.Jewelry
SaleQueue chan *models.Jewelry
StopChan chan struct{}
ProducedCount int
Mutex sync.Mutex
}
var instance *QueueManager
var once sync.Once
// GetInstance 单例模式
func GetInstance() *QueueManager {
once.Do(func() {
instance = &QueueManager{
RawQueue: make(chan *models.Jewelry, 5),
ProcessQueue: make(chan *models.Jewelry, 5),
QualityQueue: make(chan *models.Jewelry, 5),
SaleQueue: make(chan *models.Jewelry, 5),
StopChan: make(chan struct{}),
}
})
return instance
}
// IsStopped 判断是否停止
func (m *QueueManager) IsStopped() bool {
select {
case <-m.StopChan:
return true
default:
return false
}
}
// Stop 发送停止信号
func (m *QueueManager) Stop() {
close(m.StopChan)
}
// IncProducedCount 线程安全计数
func (m *QueueManager) IncProducedCount() int {
m.Mutex.Lock()
defer m.Mutex.Unlock()
m.ProducedCount++
return m.ProducedCount
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer 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/6/19 19:32
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : producer.go
*/
package service
import (
"fmt"
"godesginpattern/producerconsumer/config"
"godesginpattern/producerconsumer/core"
"godesginpattern/producerconsumer/models"
"godesginpattern/producerconsumer/utils"
)
// 原料生产者
func RawMaterialProducer() {
mgr := core.GetInstance()
for !mgr.IsStopped() {
utils.Sleep(config.TimeRaw, config.TimeRawMax)
mat := utils.RandomChoice(config.RawMaterials)
j := &models.Jewelry{
ID: utils.RandString(),
Material: mat,
Stage: models.Raw,
}
select {
case mgr.RawQueue <- j:
cnt := mgr.IncProducedCount()
utils.Info("ProducerService",
fmt.Sprintf("原料采购完成 | [原料]%s | 队列剩余: %d | 已生产:%d/%d",
mat, len(mgr.RawQueue), cnt, config.MaxProduceCount))
if cnt >= config.MaxProduceCount {
utils.Info("ProducerService", "已达到最大生产数量,准备停止生产")
mgr.Stop()
return
}
case <-mgr.StopChan:
return
}
}
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Producer Consumer 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/6/19 19:32
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : consumer.go
*/
package service
import (
"fmt"
"godesginpattern/producerconsumer/config"
"godesginpattern/producerconsumer/core"
"godesginpattern/producerconsumer/models"
"godesginpattern/producerconsumer/utils"
)
// 全流程消费者(加工 / 质检 / 仓储 / 销售)
// ProcessConsumer 加工
func ProcessConsumer() {
mgr := core.GetInstance()
for {
select {
case j := <-mgr.RawQueue:
utils.Sleep(config.TimeProcess, config.TimeProcessMax)
utils.Info("ConsumerService", fmt.Sprintf("开始加工 | [%s]%s", j.Stage, j.Material))
j.Stage = models.Processed
mgr.ProcessQueue <- j
utils.Info("ConsumerService",
fmt.Sprintf("加工完成 | [成品]%s | 队列剩余: %d", j.Material, len(mgr.ProcessQueue)))
case <-mgr.StopChan:
if len(mgr.RawQueue) == 0 {
return
}
}
}
}
// QualityConsumer 质检
func QualityConsumer() {
mgr := core.GetInstance()
for {
select {
case j := <-mgr.ProcessQueue:
utils.Sleep(config.TimeQuality, config.TimeQualityMax)
utils.Info("ConsumerService", fmt.Sprintf("开始质检 | [%s]%s", j.Stage, j.Material))
j.QualityLevel = utils.RandomChoice(config.QualityLevels)
j.Stage = models.Qualified
mgr.QualityQueue <- j
utils.Info("ConsumerService",
fmt.Sprintf("质检完成 | %s%s | 队列剩余: %d", j.QualityLevel, j.Material, len(mgr.QualityQueue)))
case <-mgr.StopChan:
if len(mgr.ProcessQueue) == 0 {
return
}
}
}
}
// WarehouseConsumer 仓储
func WarehouseConsumer() {
mgr := core.GetInstance()
for {
select {
case j := <-mgr.QualityQueue:
utils.Sleep(config.TimeWarehouse, config.TimeWarehouseMax)
utils.Info("ConsumerService", fmt.Sprintf("开始入库 | [%s]%s%s", j.Stage, j.QualityLevel, j.Material))
j.Stage = models.Salable
mgr.SaleQueue <- j
utils.Info("ConsumerService",
fmt.Sprintf("入库完成 | %s%s(已入库可销售) | 队列剩余: %d", j.QualityLevel, j.Material, len(mgr.SaleQueue)))
case <-mgr.StopChan:
if len(mgr.QualityQueue) == 0 {
return
}
}
}
}
// SaleConsumer 销售
func SaleConsumer() {
mgr := core.GetInstance()
for {
select {
case j := <-mgr.SaleQueue:
utils.Sleep(config.TimeSale, config.TimeSaleMax)
utils.Info("ConsumerService",
fmt.Sprintf("开始销售 | [可销售]%s%s(已入库可销售)", j.QualityLevel, j.Material))
utils.Info("ConsumerService",
fmt.Sprintf("销售成功 | %s%s(已入库可销售)\n", j.QualityLevel, j.Material))
case <-mgr.StopChan:
if len(mgr.SaleQueue) == 0 {
return
}
}
}
}
/*
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# 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/6/19 19:46
# User : geovindu
# Product : GoLand
# Project : godesginpattern
# File : producerconsumerbll.go
*/
package bll
import (
"fmt"
"godesginpattern/producerconsumer/config"
"godesginpattern/producerconsumer/core"
"godesginpattern/producerconsumer/service"
"godesginpattern/producerconsumer/utils"
"os"
"os/signal"
"sync"
"syscall"
)
// 启动所有 Goroutine
func ProducerConsumerMain() {
utils.Info("Main", "============================================================")
utils.Info("Main", "珠宝全流程生产销售系统(企业级生产者消费者模式)")
utils.Info("Main", fmt.Sprintf("最大生产数量限制:%d", config.MaxProduceCount))
utils.Info("Main", "============================================================")
mgr := core.GetInstance()
var wg sync.WaitGroup
// 启动生产者
for i := 0; i < config.ProducerThreads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
service.RawMaterialProducer()
}()
}
// 启动消费者
for i := 0; i < config.ProcessThreads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
service.ProcessConsumer()
}()
}
for i := 0; i < config.QualityThreads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
service.QualityConsumer()
}()
}
for i := 0; i < config.WarehouseThreads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
service.WarehouseConsumer()
}()
}
for i := 0; i < config.SaleThreads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
service.SaleConsumer()
}()
}
// 监听 Ctrl+C
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigChan
utils.Info("Main", "检测到 Ctrl+C,触发优雅停止...")
mgr.Stop()
}()
// 等待所有协程完成
wg.Wait()
utils.Info("Main", "所有业务线程已正常退出")
utils.Info("Main", "系统正常结束,输出停止")
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。