/
stack.go
110 lines (97 loc) · 1.76 KB
/
stack.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package utils
import (
"sync/atomic"
"unsafe"
"time"
)
type tNode struct {
val interface{}
next unsafe.Pointer // *tNode
}
type TStack struct {
top unsafe.Pointer // *tNode
len int32
}
func NewStack() (stack *TStack) {
return &TStack{}
}
/*
返回堆栈高度
*/
func (this *TStack)Len() int32 {
return atomic.LoadInt32(&this.len)
}
/*
数据入栈
*/
func (this *TStack)Push(_val interface{}) {
if nil != _val {
node := &tNode{val:_val}
for {
node.next = this.top
if atomic.CompareAndSwapPointer(&this.top, node.next, unsafe.Pointer(node)) {
atomic.AddInt32(&this.len, 1)
break
}
}
}
}
func (this *TStack)Pop() (interface{}, bool) {
for {
top := this.top
if nil == top {
return nil, false
} else {
node := (*tNode)(top)
if atomic.CompareAndSwapPointer(&this.top, top, node.next) {
atomic.AddInt32(&this.len, -1)
return node.val, true
}
}
}
return nil, false
}
func TestStack() {
println("testStack")
stack := NewStack()
type node struct {
val int
}
println("setup")
for i := 0; i < 1024; i++ {
stack.Push(&node{val:i})
}
println("go 1")
go func() {
for {
if val, ok := stack.Pop(); ok {
nd := val.(*node)
println("1.pop= ", nd.val)
stack.Push(nd)
}
println("-----")
time.Sleep(time.Millisecond)
}
}()
println("go 2")
go func() {
for {
if val, ok := stack.Pop(); ok {
nd := val.(*node)
println("2.pop= ", nd.val)
stack.Push(nd)
}
println("========")
time.Sleep(time.Millisecond)
}
}()
tm := time.NewTimer(time.Second * 5)
println("start timer")
for {
select {
case <-tm.C:
println("time")
tm.Reset(time.Second * 5)
}
}
}