首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
// 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("栈已为空,弹出失败")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user