定义
状态机比较简单,就类似于数字一样,由1,2,3,4,5这几个数组成一个整体,这个整体就叫做状态机,其中的每一个数就叫做状态机的状态。
也可以参考维基百科的定义
有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机(英语:finite-state automaton,缩写:FSA),简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型。
具体实现
package statemachine
import (
"fmt"
"sync"
"time"
)
type List struct {
lock sync.RWMutex
nodes []*Node
}
type Node struct {
Tm int64
State STATE
}
// 定义状态机状态
type STATE int
const (
Close = STATE(iota)
HalfOpen
Open
)
var list = &List{lock: sync.RWMutex{}, nodes: make([]*Node, 0)}
func (l *List) AppendNode(node *Node) {
l.lock.Lock()
l.nodes = append(l.nodes, node)
l.lock.Unlock()
}
// 模拟消息队列一直处理队列中的节点信息,所有状态走完,则移出消息队列
func ChangeState() {
for {
time.Sleep(time.Second * 1)
list.lock.Lock()
tmpNodes := make([]*Node, 0)
for k := range list.nodes {
node := list.nodes[k]
if time.Now().Unix() > node.Tm+6 {
node.State = Open
} else if time.Now().Unix() > node.Tm+3 {
node.State = HalfOpen
} else {
node.State = Close
}
if node.State != Open {
tmpNodes = append(tmpNodes, node)
}
fmt.Println("k:", k, " state:", node.State)
}
// 重建node列表
if len(list.nodes) != len(tmpNodes) {
list.nodes = tmpNodes
}
list.lock.Unlock()
}
}
测试用例
package statemachine
import (
"testing"
"time"
)
func TestStateMachine(t *testing.T) {
go ChangeState()
for i := 0; i < 10; i++ {
list.AppendNode(&Node{Tm: time.Now().Unix()})
// 控制时间,看离散分布
//n := rand.Intn(6)
//time.Sleep(time.Second * time.Duration(n))
time.Sleep(time.Second)
}
time.Sleep(time.Second * 10)
}
输出
=== RUN TestStateMachine
k: 0 state: 0
k: 0 state: 0
k: 1 state: 0
k: 0 state: 0
k: 1 state: 0
k: 2 state: 0
k: 0 state: 1
k: 1 state: 0
k: 2 state: 0
k: 3 state: 0
k: 4 state: 0
k: 0 state: 1
k: 1 state: 1
k: 2 state: 0
k: 3 state: 0
k: 4 state: 0
k: 0 state: 1
k: 1 state: 1
k: 2 state: 1
k: 3 state: 0
k: 4 state: 0
k: 5 state: 0
k: 6 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 4 state: 0
k: 5 state: 0
k: 6 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 4 state: 0
k: 5 state: 0
k: 6 state: 0
k: 7 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 4 state: 0
k: 5 state: 0
k: 6 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 4 state: 0
k: 5 state: 0
k: 6 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 4 state: 0
k: 5 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 4 state: 0
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 3 state: 1
k: 0 state: 2
k: 1 state: 1
k: 2 state: 1
k: 0 state: 2
k: 1 state: 1
k: 0 state: 2
--- PASS: TestStateMachine (20.03s)
PASS
总结
总体定义和实现比较简单,一般状态机结合定时任务或者消息队列触发可能会比较好一点,也可能是手动触发的状态轮转。