Thread-Safe Array, Slice, Map, Queue & Stack in Go

Concurrency is a crucial aspect of modern software development, enabling efficient use of resources and improved performance. However, managing shared data between concurrent operations can lead to race conditions and data inconsistencies. The threadsafe package by Ravishanker Kusuma provides a solution by offering thread-safe implementations of common data structures like arrays, slices, maps, stacks, and queues.

Thread Safe Array

Why Thread Safety is Important

When multiple goroutines access shared data simultaneously, it can lead to unpredictable behavior and bugs that are hard to reproduce and fix. Thread-safe data structures ensure that concurrent accesses are managed correctly, preventing race conditions and ensuring data integrity.

Key Features of the threadsafe Package

The threadsafe package provides generic implementations of arrays, slices, maps, stacks, and queues. These implementations use Go’s generics and type constraints to ensure that operations on these data structures are safe to perform from multiple goroutines.

Thread-Safe Array

A fixed-size array that provides safe concurrent access to its elements.

API:

  • NewArray[T any](size int) *Array[T]
  • (*Array[T]).Get(index int) (T, error)
  • (*Array[T]).Set(index int, value T) error
  • (*Array[T]).Len() int
package main

import (
    "fmt"
    "github.com/hayageek/threadsafe"
)

func main() {
    arr := threadsafe.NewArray[int](1) 
    arr.Set(0, 10)
    value, _ := arr.Get(0)
    fmt.Println(value) // Output: 10
}

Thread-Safe Slice

A dynamically sized slice with safe concurrent operations.

API:

  • NewSlice[T any]() *Slice[T]
  • (*Slice[T]).Append(value T)
  • (*Slice[T]).Get(index int) (T, error)
  • (*Slice[T]).Set(index int, value T) error
  • (*Slice[T]).Len() int
package main

import (
    "fmt"
    "github.com/hayageek/threadsafe"
)

func main() {
    slice := threadsafe.NewSlice[int]()
    slice.Append(10)
    value, _ := slice.Get(0)
    fmt.Println(value) // Output: 10
}

Thread-Safe Map

A key-value store that supports safe concurrent access.

API:

  • NewMap[K comparable, V any]() *Map[K, V]
  • (*Map[K, V]).Get(key K) (V, bool)
  • (*Map[K, V]).Set(key K, value V)
  • (*Map[K, V]).Delete(key K)
  • (*Map[K, V]).Len() int

Example:

package main

import (
    "fmt"
    "github.com/hayageek/threadsafe"
)

func main() {
    m := threadsafe.NewMap[string, int]()
    m.Set("key", 10)
    value, _ := m.Get("key")
    fmt.Println(value) // Output: 10
}

 

Thread-Safe Stack

A LIFO (Last In, First Out) stack with safe concurrent operations.

API:

  • NewStack[T any]() *Stack[T]
  • (*Stack[T]).Push(value T)
  • (*Stack[T]).Pop() (T, error)
  • (*Stack[T]).Peek() (T, error)
  • (*Stack[T]).Len() int

Example:

package main

import (
    "fmt"
    "github.com/hayageek/threadsafe"
)

func main() {
    stack := threadsafe.NewStack[int]()
    stack.Push(10)
    value, _ := stack.Pop()
    fmt.Println(value) // Output: 10
}

 

Thread-Safe Queue

A FIFO (First In, First Out) queue with safe concurrent operations.

API:

  • NewQueue[T any]() *Queue[T]
  • (*Queue[T]).Enqueue(value T)
  • (*Queue[T]).Dequeue() (T, error)
  • (*Queue[T]).Peek() (T, error)
  • (*Queue[T]).Len() int

Example:

package main

import (
    "fmt"
    "github.com/hayageek/threadsafe"
)

func main() {
    queue := threadsafe.NewQueue[int]()
    queue.Enqueue(10)
    value, _ := queue.Dequeue()
    fmt.Println(value) // Output: 10
}

Conclusion

The threadsafe package is an essential tool for Go developers looking to manage concurrent operations safely. By providing thread-safe implementations of common data structures, it simplifies the process of writing concurrent code and helps prevent subtle concurrency bugs.

For more details, visit the threadsafe GitHub repository.