Skip to content
Go concurrent-safe, goroutine-safe, thread-safe queue
Branch: master
Clone or download
Latest commit 4212a49 Jun 4, 2019

godoc reference version Go Report Card Build Status codecov

goconcurrentqueue - Concurrent safe queues

The package goconcurrentqueue offers a public interface Queue with methods for a queue. It comes with multiple Queue's concurrent-safe implementations, meaning they could be used concurrently by multiple goroutines without adding race conditions.




go get

This package is compatible with the following golang versions:

  • 1.7.x
  • 1.8.x
  • 1.9.x
  • 1.10.x
  • 1.11.x
  • 1.12.x


Visit goconcurrentqueue at



FIFO: concurrent-safe auto expandable queue.


  • It is possible to enqueue as many items as needed.
  • Extra methods to get and remove enqueued items:
    • Get: returns an element's value and keeps the element at the queue
    • Remove: removes an element (using a given position) from the queue


  • It is slightly slower than FixedFIFO.


FixedFIFO: concurrent-safe fixed capacity queue.


  • FixedFIFO is, at least, 2x faster than FIFO in concurrent scenarios (multiple GR accessing the queue simultaneously).


  • It has a fixed capacity meaning that no more items than this capacity could coexist at the same time.

Benchmarks FixedFIFO vs FIFO

The numbers for the following charts were obtained by running the benchmarks in a 2012 MacBook Pro (2.3 GHz Intel Core i7 - 16 GB 1600 MHz DDR3) with golang v1.12


concurrent-safe FixedFIFO vs FIFO . operation: enqueue


concurrent-safe FixedFIFO vs FIFO . operation: dequeue

Get started

FIFO queue simple usage

package main

import (


type AnyStruct struct {
	Field1 string
	Field2 int

func main() {
	queue := goconcurrentqueue.NewFIFO()

	queue.Enqueue("any string value")
	queue.Enqueue(AnyStruct{Field1: "hello world", Field2: 15})

	// will output: 3
	fmt.Printf("queue's length: %v\n", queue.GetLen())

	item, err := queue.Dequeue()
	if err != nil {

	// will output "any string value"
	fmt.Printf("dequeued item: %v\n", item)

	// will output: 2
	fmt.Printf("queue's length: %v\n", queue.GetLen())


Wait until an element gets enqueued

package main

import (


func main() {
	var (
		fifo = goconcurrentqueue.NewFIFO()
		done = make(chan struct{})

	go func() {
		fmt.Println("1 - Waiting for next enqueued element")
		value, _ := fifo.DequeueOrWaitForNextElement()
		fmt.Printf("2 - Dequeued element: %v\n", value)

		done <- struct{}{}

	fmt.Println("3 - Go to sleep for 3 seconds")
	time.Sleep(3 * time.Second)

	fmt.Println("4 - Enqueue element")


Dependency Inversion Principle using concurrent-safe queues

High level modules should not depend on low level modules. Both should depend on abstractions. Robert C. Martin

package main

import (


func main() {
	var (
		queue          goconcurrentqueue.Queue
		dummyCondition = true

	// decides which Queue's implementation is the best option for this scenario
	if dummyCondition {
		queue = goconcurrentqueue.NewFIFO()
	} else {
		queue = goconcurrentqueue.NewFixedFIFO(10)

	fmt.Printf("queue's length: %v\n", queue.GetLen())
	fmt.Printf("queue's length: %v\n", queue.GetLen())

// workWithQueue uses a goconcurrentqueue.Queue to perform the work
func workWithQueue(queue goconcurrentqueue.Queue) error {
	// do some work

	// enqueue an item
	if err := queue.Enqueue("test value"); err != nil {
		return err

	return nil



  • Added DequeueOrWaitForNextElement()


  • Added QueueError (custom error)


  • Added FixedFIFO queue's implementation (at least 2x faster than FIFO for multiple GRs)
  • Added benchmarks for both FIFO / FixedFIFO
  • Added GetCap() to Queue interface
  • Removed Get() and Remove() methods from Queue interface


  • Added Lock/Unlock/IsLocked methods to control operations locking


  • First In First Out (FIFO) queue added
You can’t perform that action at this time.