golang线程安全通用队列实现插件库queue的使用
Golang线程安全通用队列实现插件库queue的使用
queue
包提供了Go中线程安全的通用实现,包括以下几种数据结构:BlockingQueue
、PriorityQueue
、CircularQueue
和Linked Queue
。
安装
要添加此包作为项目依赖项,请运行:
go get -u github.com/adrianbrad/queue
导入
在项目中导入:
import "github.com/adrianbrad/queue"
使用
Queue接口
// Queue是通用队列接口,定义了所有队列必须实现的方法
type Queue[T comparable] interface {
// Get 检索并移除队列头部元素
Get() (T, error)
// Offer 将元素插入队列尾部
Offer(T) error
// Reset 将队列重置为初始状态
Reset()
// Contains 如果队列包含该元素则返回true
Contains(T) bool
// Peek 检索但不移除队列头部元素
Peek() (T, error)
// Size 返回队列中元素数量
Size() int
// IsEmpty 如果队列为空则返回true
IsEmpty() bool
// Iterator 返回一个将被元素填充的通道
Iterator() <-chan T
// Clear 移除队列中所有元素
Clear() []T
}
阻塞队列(Blocking Queue)
阻塞队列是FIFO有序数据结构。实现了阻塞和非阻塞方法。
package main
import (
"fmt"
"github.com/adrianbrad/queue"
)
func main() {
elems := []int{2, 3}
blockingQueue := queue.NewBlocking(elems, queue.WithCapacity(3))
containsTwo := blockingQueue.Contains(2)
fmt.Println(containsTwo) // true
size := blockingQueue.Size()
fmt.Println(size) // 2
empty := blockingQueue.IsEmpty()
fmt.Println(empty) // false
if err := blockingQueue.Offer(1); err != nil {
// 处理错误
}
elem, err := blockingQueue.Get()
if err != nil {
// 处理错误
}
fmt.Println("elem: ", elem) // elem: 2
}
优先级队列(Priority Queue)
优先级队列中元素的顺序由构造时提供的比较函数决定。
package main
import (
"fmt"
"github.com/adrianbrad/queue"
)
func main() {
elems := []int{2, 3, 4}
priorityQueue := queue.NewPriority(
elems,
func(elem, otherElem int) bool { return elem < otherElem },
)
containsTwo := priorityQueue.Contains(2)
fmt.Println(containsTwo) // true
size := priorityQueue.Size()
fmt.Println(size) // 3
empty := priorityQueue.IsEmpty()
fmt.Println(empty) // false
if err := priorityQueue.Offer(1); err != nil {
// 处理错误
}
elem, err := priorityQueue.Get()
if err != nil {
// 处理错误
}
fmt.Printf("elem: %d\n", elem) // elem: 1
}
循环队列(Circular Queue)
循环队列是固定大小的FIFO有序数据结构。当队列满时,添加新元素会覆盖最旧的元素。
package main
import (
"fmt"
"github.com/adrianbrad/queue"
)
func main() {
elems := []int{2, 3, 4}
circularQueue := queue.NewCircular(elems, 3)
containsTwo := circularQueue.Contains(2)
fmt.Println(containsTwo) // true
size := circularQueue.Size()
fmt.Println(size) // 3
empty := circularQueue.IsEmpty()
fmt.Println(empty) // false
if err := circularQueue.Offer(1); err != nil {
// 处理错误
}
elem, err := circularQueue.Get()
if err != nil {
// 处理错误
}
fmt.Printf("elem: %d\n", elem) // elem: 1
}
链式队列(Linked Queue)
链式队列实现为单链表,提供O(1)时间复杂度的入队和出队操作。
package main
import (
"fmt"
"github.com/adrianbrad/queue"
)
func main() {
elems := []int{2, 3, 4}
circularQueue := queue.NewLinked(elems)
containsTwo := circularQueue.Contains(2)
fmt.Println(containsTwo) // true
size := circularQueue.Size()
fmt.Println(size) // 3
empty := circularQueue.IsEmpty()
fmt.Println(empty) // false
if err := circularQueue.Offer(1); err != nil {
// 处理错误
}
elem, err := circularQueue.Get()
if err != nil {
// 处理错误
}
fmt.Printf("elem: %d\n", elem) // elem: 2
}
基准测试
2023年10月测试结果:
BenchmarkBlockingQueue/Peek-8 84873882 13.98 ns/op 0 B/op 0 allocs/op
BenchmarkBlockingQueue/Get_Offer-8 27135865 47.00 ns/op 44 B/op 0 allocs/op
BenchmarkBlockingQueue/Offer-8 53750395 25.40 ns/op 43 B/op 0 allocs/op
BenchmarkCircularQueue/Peek-8 86001980 13.76 ns/op 0 B/op 0 allocs/op
BenchmarkCircularQueue/Get_Offer-8 32379159 36.83 ns/op 0 B/op 0 allocs/op
BenchmarkCircularQueue/Offer-8 63956366 18.77 ns/op 0 B/op 0 allocs/op
BenchmarkLinkedQueue/Peek-8 1000000000 0.4179 ns/op 0 B/op 0 allocs/op
BenchmarkLinkedQueue/Get_Offer-8 61257436 18.48 ns/op 16 B/op 1 allocs/op
BenchmarkLinkedQueue/Offer-8 38975062 30.74 ns/op 16 B/op 1 allocs/op
BenchmarkPriorityQueue/Peek-8 86633734 14.02 ns/op 0 B/op 0 allocs/op
BenchmarkPriorityQueue/Get_Offer-8 29347177 39.88 ns/op 0 B/op 0 allocs/op
BenchmarkPriorityQueue/Offer-8 40117958 31.37 ns/op 54 B/op 0 allocs/op
更多关于golang线程安全通用队列实现插件库queue的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复