В стандартной библиотеке Go нет готовых очередей. Можно написать свою на слайсах, но тогда придётся самому думать о race conditions, блокировках и сбросе состояния. Пакет
queue от adrianbrad закрывает эту задачу: четыре реализации с единым интерфейсом и встроенной потокобезопасностью.Что внутри
Все структуры реализуют один интерфейс
Queue[T comparable]. Методы одинаковые у всех: Get, Offer, Peek, Contains, Size, IsEmpty, Reset, Clear, Iterator.Четыре реализации:
BlockingQueue — FIFO с блокирующими методами. Если очередь пуста, Get ждёт. Если заполнена, Offer ждёт. Внутри использует sync.Cond. Подходит для классических producer-consumer задач.PriorityQueue — порядок элементов задаётся функцией-компаратором. Реализована через container/heap. Полезна, когда нужно обрабатывать задачи не по порядку прихода, а по приоритету.CircularQueue — кольцевой буфер фиксированного размера. Когда буфер заполнен, новый элемент перезаписывает самый старый. Удобна для логов, кешей скользящего окна, буферизации потоков.LinkedQueue — связный список, O(1) на добавление и удаление. Хранит указатели на голову и хвост, поэтому не нужен обход списка.Установка:
go get -u github.com/adrianbrad/queue
Пример BlockingQueue:
package main
import (
"fmt"
"github.com/adrianbrad/queue"
)
func main() {
elems := []int{2, 3}
bq := queue.NewBlocking(elems, queue.WithCapacity(3))
_ = bq.Offer(1)
elem, err := bq.Get()
if err != nil {
// handle err
}
fmt.Println(elem) // 2
}
Пример PriorityQueue:
pq := queue.NewPriority(
[]int{2, 3, 4},
func(a, b int) bool { return a < b },
)
_ = pq.Offer(1)
elem, _ := pq.Get()
fmt.Println(elem) // 1 — минимальный элемент
Бенчмарки:
BenchmarkBlockingQueue/Get_Offer-8 27135865 47.00 ns/op
BenchmarkCircularQueue/Get_Offer-8 32379159 36.83 ns/op
BenchmarkLinkedQueue/Get_Offer-8 61257436 18.48 ns/op
BenchmarkPriorityQueue/Get_Offer-8 29347177 39.88 ns/op
LinkedQueue самый быстрый на Get/Offer. CircularQueue не делает аллокаций при операциях, что важно под нагрузкой.➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
