// bulma/atomic_stack.go package main import ( "fmt" "sync/atomic" ) // StackNode 无锁栈节点(泛型,支持任意数据类型) type StackNode[T any] struct { Value T Next *StackNode[T] // 指向栈底节点 } // LockFreeStack 无锁栈(基于atomic.Pointer实现) type LockFreeStack[T any] struct { head atomic.Pointer[StackNode[T]] // 栈顶指针(原子指针) } // Push 入栈:通过CAS操作替换栈顶,保证并发安全 func (s *LockFreeStack[T]) Push(val T) { for { oldHead := s.head.Load() newHead := &StackNode[T]{Value: val, Next: oldHead} // CAS操作成功则入栈完成,失败则重试(避免并发冲突) if s.head.CompareAndSwap(oldHead, newHead) { return // CAS 成功,退出 } // CAS 失败(被其他 goroutine 修改),重试 } } // Pop 出栈:通过CAS操作替换栈顶为下一个节点,无元素时返回false func (s *LockFreeStack[T]) Pop() (T, bool) { for { oldHead := s.head.Load() if oldHead == nil { var zero T // 空值,对应泛型默认零值 return zero, false } // CAS操作成功则出栈完成,返回栈顶元素 if s.head.CompareAndSwap(oldHead, oldHead.Next) { return oldHead.Value, true } } } func main() { stack := &LockFreeStack[int]{} // 入栈3个元素(10、20、30) stack.Push(10) stack.Push(20) stack.Push(30) // 出栈(LIFO:后进先出,依次弹出30、20、10) for i := 0; i < 3; i++ { if val, ok := stack.Pop(); ok { fmt.Printf("✅ 弹出: %d\n", val) } } // 空栈测试:弹出操作失败 if _, ok := stack.Pop(); !ok { fmt.Println("栈已为空,弹出失败") } }