go / expert
Snippet
Lock-Free Concurrent Stack using Generic Atomic Pointers
This snippet demonstrates how to construct a lock-free thread-safe stack using Go 1.19+ atomic.Pointer[T] generics. By employing a Compare-And-Swap (CAS) retry loop, lock contention overhead is minimized while preserving memory safety across concurrent goroutines.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package mainimport ("sync/atomic")type Node[T any] struct {Value Tnext *Node[T]}type LockFreeStack[T any] struct {head atomic.Pointer[Node[T]]}func (s *LockFreeStack[T]) Push(val T) {newHead := &Node[T]{Value: val}for {currHead := s.head.Load()newHead.next = currHeadif s.head.CompareAndSwap(currHead, newHead) {return}}}func (s *LockFreeStack[T]) Pop() (T, bool) {for {currHead := s.head.Load()if currHead == nil {var zero Treturn zero, false}nextHead := currHead.nextif s.head.CompareAndSwap(currHead, nextHead) {return currHead.Value, true}}}
Breakdown
1
type LockFreeStack[T any] struct { head atomic.Pointer[Node[T]] }
Defines a generic concurrent stack structure wrapping an atomic pointer to the top node.
2
if s.head.CompareAndSwap(currHead, newHead) { return }
Atomically updates the head pointer only if it matches the expected current node, retrying if preempted.