package main
import (
"fmt"
"sync"
)
// FiniteQueue 限定容量的队列
type FiniteQueue struct {
queue []interface{}
capacity int
mutex sync.Mutex
notEmpty *sync.Cond
notFull *sync.Cond
}
func NewFiniteQueue(capacity int) *FiniteQueue {
if capacity < 1 {
panic("capacity must be greater than 1")
}
bq := &FiniteQueue{
capacity: capacity,
queue: make([]interface{}, 0, capacity), // 创建一个长度为0,容量为capacity的切片
}
bq.notEmpty = sync.NewCond(&bq.mutex) // 使用 FiniteQueue 自身的互斥锁
bq.notFull = sync.NewCond(&bq.mutex) // 使用 FiniteQueue 自身的互斥锁
return bq
}
// Enqueue 将元素添加到队列,如果队列已满则阻塞
func (bq *FiniteQueue) Enqueue(v interface{}) {
bq.mutex.Lock()
defer bq.mutex.Unlock()
for len(bq.queue) == bq.capacity { // 等待队列不满
bq.notFull.Wait()
}
bq.queue = append(bq.queue, v)
bq.notEmpty.Signal() // 通知消费者
}
func (bq *FiniteQueue) Dequeue() interface{} {
bq.mutex.Lock()
defer bq.mutex.Unlock()
// 等待队列不为空的情况
for len(bq.queue) == 0 {
bq.notEmpty.Wait()
}
item := bq.queue[0]
bq.queue = bq.queue[1:]
bq.notFull.Signal() // 通知生产者
return item
}
func (bq *FiniteQueue) Len() int {
bq.mutex.Lock()
defer bq.mutex.Unlock()
return len(bq.queue)
}
func main() {
bq := NewFiniteQueue(5)
// producer
go func() {
for i := 0; i < 10; i++ {
bq.Enqueue(i)
fmt.Printf("Add: %d, Size: %d\n", i, bq.Len()) // 使用 Len() 方法
}
}()
// consumer
go func() {
for i := 0; i < 10; i++ {
item := bq.Dequeue()
fmt.Printf("Dequeue: %v, Size: %d\n", item, bq.Len()) // 使用 Len() 方法
}
}()
var input string
fmt.Scanln(&input)
}