go实现状态机(简易版)

定义

状态机比较简单,就类似于数字一样,由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

总结

总体定义和实现比较简单,一般状态机结合定时任务或者消息队列触发可能会比较好一点,也可能是手动触发的状态轮转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值