使用channel和sync.Mutex可实现Go并发队列。带缓冲channel支持多生产者消费者,代码简洁高效;自定义slice+mutex+cond适用于需阻塞或复杂控制的场景。

在Go语言中实现并发队列,核心是利用 channel 和 goroutine 的天然并发支持。Golang的channel本身就是线程安全的,非常适合用来构建高效的并发队列,无需手动加锁。下面介绍几种常见的实现方式和使用场景。
使用带缓冲的Channel作为并发队列
最简单且高效的方式是使用带缓冲的channel。它天然支持多个生产者和消费者并发操作。
示例:
package mainimport ("fmt""time")
func main() {// 创建一个容量为5的整型队列queue := make(chan int, 5)
// 启动消费者go func() { for num := range queue { fmt.Printf("消费: %dn", num) time.Sleep(100 * time.Millisecond) // 模拟处理时间 }}()// 生产者发送数据for i := 1; i <= 10; i++ { queue <- i fmt.Printf("生产: %dn", i)}close(queue) // 关闭channel,通知消费者结束time.Sleep(2 * time.Second) // 等待消费完成}
这种方式适用于大多数场景,代码简洁,性能好。
使用sync.Mutex保护的Slice队列(自定义结构)
如果需要更复杂的队列行为(如优先级、超时、动态扩容),可以基于slice + mutex实现。
立即学习“go语言免费学习笔记(深入)”;
示例:
package mainimport ("container/list""fmt""sync")
type Queue struct {data list.Listmu sync.Mutexcond sync.Cond}
func NewQueue() *Queue {q := &Queue{data: list.New(),}q.cond = sync.NewCond(&q.mu)return q}
func (q *Queue) Push(value interface{}) {q.mu.Lock()q.data.PushBack(value)q.mu.Unlock()q.cond.Signal() // 唤醒等待的消费者}
func (q *Queue) Pop() interface{} {q.mu.Lock()defer q.mu.Unlock()
for q.data.Len() == 0 { q.cond.Wait() // 阻塞直到有数据}e := q.data.Front()q.data.Remove(e)return e.Value}
bee餐饮点餐外卖小程序
bee餐饮点餐外卖小程序是针对餐饮行业推出的一套完整的餐饮解决方案,实现了用户在线点餐下单、外卖、叫号排队、支付、配送等功能,完美的使餐饮行业更高效便捷!功能演示:1、桌号管理登录后台,左侧菜单 “桌号管理”,添加并管理你的桌号信息,添加以后在列表你将可以看到 ID 和 密钥,这两个数据用来生成桌子的二维码2、生成桌子二维码例如上面的ID为 308,密钥为 d3PiIY,那么现在去左侧菜单微信设置
1 查看详情
![]()
func (q *Queue) Len() int {q.mu.Lock()defer q.mu.Unlock()return q.data.Len()}
这种实现适合需要阻塞读取或精细控制的场景。sync.Cond用于避免忙等,提升效率。
多生产者-多消费者模型实战
实际项目中常遇到多个goroutine同时读写队列的情况。下面是一个完整例子:
// 启动多个生产者for i := 0; i < 3; i++ { go func(id int) { for j := 0; j < 5; j++ { queue <- fmt.Sprintf("消息-%d-%d", id, j) time.Sleep(50 * time.Millisecond) } }(i)}// 启动多个消费者for i := 0; i < 2; i++ {go func(id int) {for msg := range queue {fmt.Printf("消费者%d处理: %sn", id, msg)time.Sleep(100 * time.Millisecond)}}(i)}
注意:需确保所有生产者完成后关闭channel,否则消费者会一直阻塞。可以用sync.WaitGroup协调。
基本上就这些。用channel是最推荐的方式,足够安全又高效。只有在标准channel无法满足需求时,才考虑用锁+slice的方案。关键是理解Go的并发哲学:通过通信共享内存,而不是通过共享内存通信。
以上就是如何使用Golang实现并发队列的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1142597.html
微信扫一扫
支付宝扫一扫