环形队列
环形队列的优点
保证元素是先进先出的。是由队列的性质保证的,在环形队列中通过对队列的顺序访问保证。
元素空间可以重复利用。因为一般的环形队列都是一个元素数固定的一个闭环,可以在环形队列初始化的时候分配好确定的内存空间,当进队或出队时只需要返回指定元素内存空间的地址即可,这些内存空间可以重复利用,避免频繁内存分配和释放的开销。
为多线程数据通信提供了一种高效的机制。在最典型的生产者消费者模型中,如果引入环形队列,那么生成者只需要生成“东西”然后放到环形队列中即可,而消费者只需要从环形队列里取“东西”并且消费即可,没有任何锁或者等待,巧妙的高效实现了多线程数据通信。
接口
package ring_queue
type RingQueueInterface interface {
// 获取队列中元素个数
Len() int
// 获取队首元素
Head() interface{}
// 获取队尾元素
Tail() interface{}
// 从队尾添加元素
Insert(x interface{}) bool
// 移除队首元素
LPop() bool
// 队列已满
IsFull() bool
// 队列为空
Empty() bool
}
type RingDequeInterface interface {
// 移除队尾元素
Pop() bool
// 从队首添加元素
LInsert(x interface{}) bool
RingQueueInterface
}环形队列(阻塞版,环形缓冲器)实现
当队列元素满时,不能继续插入元素。 无锁版也支持多线程,已验证数据安全性,也就是没有必要使用加读写锁的环形队列
阻塞版环形队列 PK channel
阻塞版环形队列较优
有锁版环形队列 PK 无锁版环形队列
无锁版环形队列对并发的支持(验证性实验)
环形队列(阻塞版)小结
建议使用无锁版环形队列,它支持并发操作
环形队列(非阻塞版)实现 TODO: 待实现以及数据验证
github.com/1005281342/basic_component/ring_queue_nonblocking
需要考虑在队列中没有元素时执行pop(弹出)动作,在本实现中不会提示队列为空切返回的元素为nil。
注意在本实现中如果队列满了继续插入元素则会覆盖队尾元素(队尾元素会被弹出)。
参考
https://github.com/el10savio/goCircularRingBuffer/blob/master/ringbuffer/ringbuffer.go
https://github.com/cxt90730/safe-queue/blob/master/Queue.go(可以利用读写锁对其进行优化)
最后更新于
这有帮助吗?