必须用 make 初始化通道,nil 通道收发会永久阻塞;无缓冲通道需收发双方同时就绪,带缓冲通道(如 make(chan int, 5))可暂存指定数量元素。

channel 创建必须指定元素类型,不能创建 nil 通道直接发送
Go 中 chan 是引用类型,但声明后若未初始化就是 nil。对 nil 通道执行 send 或 receive 会永久阻塞——这不是 bug,而是语言设计特性,常被误认为死锁。
- 正确方式:用
make(chan int)或make(chan string, 10)初始化 - 带缓冲的通道(如
make(chan int, 5))可暂存 5 个值,满后才阻塞发送;无缓冲通道(make(chan int))要求收发双方同时就绪,否则阻塞 - 避免写
var ch chan int后直接ch ,这会卡住整个 goroutine
关闭 channel 要谨慎,只应在发送方关闭,且关闭后不可再发送
close() 是单向操作,仅用于通知接收方“不会再有新数据”,不是释放资源的手段。多次关闭或在已关闭通道上发送会 panic:panic: send on closed channel。
- 只由**明确负责发送的 goroutine** 调用
close(ch),例如循环结束后 - 接收方用
v, ok := 判断是否关闭:ok为false表示通道已关闭且无剩余数据 - 不要用
defer close(ch)包裹在 goroutine 入口——可能在其他协程还在读时就关了
select 配合 channel 实现非阻塞通信和超时控制
select 是 Go 处理多通道协作的核心语法,它随机选择一个就绪的 case 执行。没有就绪 case 时,默认阻塞;加 default 则变成非阻塞轮询。
- 超时场景:把
time.After(3 * time.Second)当作一个chan time.Time放进select,配合case 可中断等待 - 避免
select {}空语句,它会永久阻塞,等价于for {} - 多个
case同时就绪时,Go 随机选一个,不保证顺序——别依赖执行次序做逻辑判断
channel 不是万能队列,高吞吐场景下要考虑缓冲大小与 Goroutine 泄漏风险
通道本质是同步原语,不是高性能消息队列。盲目加大缓冲或启动过多 goroutine 监听通道,容易引发内存暴涨或 goroutine 泄漏。
本文档主要讲述的是maven使用方法;Maven是基于项目对象模型的(pom),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。Maven将你的注意力从昨夜基层转移到项目管理层。Maven项目已经能够知道 如何构建和捆绑代码,运行测试,生成文档并宿主项目网页。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
立即学习“go语言免费学习笔记(深入)”;
- 缓冲大小不是越大越好:设为
make(chan int, 1000)可能掩盖背压问题,下游消费慢时数据全堆在内存里 - 监听通道的 goroutine 必须有退出机制,比如配合
context.Context或接收关闭信号,否则一旦通道不再写入,goroutine 就永远卡在 - 替代方案考虑:简单生产者-消费者用带缓冲 channel + 显式关闭;复杂流控建议引入
sync.WaitGroup或第三方库如go-flow
实际写并发逻辑时,最容易被忽略的是「谁关通道」和「谁该退出」这两个边界问题。哪怕代码编译通过、跑起来不 panic,只要 goroutine 数量随时间增长,大概率是通道生命周期没管好。









