下面是一个示例代码,演示如何使用 Go 语言中的 channel 和 goroutine 实现上述功能:
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 5) // 创建一个大小为 5 的缓冲 channel
go func() {
for {
data := <-ch // 从 channel 中读取数据
// 模拟复杂的处理过程,例如对数据进行排序
fmt.Println("Processing data:", data)
for i := 0; i < len(data); i++ {
for j := i + 1; j < len(data); j++ {
if data[j] < data[i] {
temp := data[j]
data[j] = data[i]
data[i] = temp
}
}
}
fmt.Println("Processed data:", data)
}
}()
go func() {
var newData int
for {
select {
case ch <- newData: // 往 channel 中写入新数据
fmt.Println("Added new data:", newData)
default:
removedData := <-ch // 移除最后一个数据并接收新数据
ch <- newData // 将新数据插入到末尾
fmt.Println("Removed old data:", removedData)
fmt.Println("Added new data:", newData)
}
newData++ // 模拟生成新的数据
}
}()
select {} // 等待程序运行结束
}
在这个示例代码中,我们首先创建了一个大小为 5 的缓冲 channel ch。然后,我们创建了两个 goroutine:
- 协程 A:负责从 channel 中读取数据,并进行复杂的处理过程。这里我们使用一个无限循环来不断接收 channel 中的数据,然后对其进行排序等复杂操作。
- 协程 B:负责往 channel 中写入新数据。如果 channel 已满,则会先移除最后一个数据并将新数据插入到末尾。
在协程 B 中,我们使用了 select 语句和 default 分支来实现向缓冲 channel 写入新数据时的逻辑判断。如果 channel 还有剩余空间,则直接向其中写入新数据;否则,我们首先从缓冲 channel 中取出最旧的一条消息,然后再将新消息插入到队列末尾。
最后,在主 goroutine 中使用了一个无限循环 select {} 来阻塞程序运行,以保证两个协程能够持续工作。




