chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring狀態(tài)機(jī)存在的問(wèn)題

jf_ro2CN3Fa ? 來(lái)源:芋道源碼 ? 2023-05-22 11:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1、什么是狀態(tài)機(jī)

1.1 什么是狀態(tài)

1.2 四大概念

1.3 狀態(tài)機(jī)

2、狀態(tài)機(jī)圖

3、spring statemachine

3.1 狀態(tài)機(jī)spring statemachine 概述

3.2 快速開(kāi)始

3.3 測(cè)試驗(yàn)證

3.4 狀態(tài)機(jī)存在的問(wèn)題

1、什么是狀態(tài)機(jī)

1.1 什么是狀態(tài)

先來(lái)解釋什么是“狀態(tài)”( State )?,F(xiàn)實(shí)事物是有不同狀態(tài)的,例如一個(gè)自動(dòng)門(mén),就有 open 和 closed 兩種狀態(tài)。我們通常所說(shuō)的狀態(tài)機(jī)是有限狀態(tài)機(jī),也就是被描述的事物的狀態(tài)的數(shù)量是有限個(gè),例如自動(dòng)門(mén)的狀態(tài)就是兩個(gè) open 和 closed 。

eeff0844-f84b-11ed-90ce-dac502259ad0.jpg

狀態(tài)機(jī),也就是 State Machine ,不是指一臺(tái)實(shí)際機(jī)器,而是指一個(gè)數(shù)學(xué)模型。說(shuō)白了,一般就是指一張狀態(tài)轉(zhuǎn)換圖。例如,根據(jù)自動(dòng)門(mén)的運(yùn)行規(guī)則,我們可以抽象出下面這么一個(gè)圖。

自動(dòng)門(mén)有兩個(gè)狀態(tài),open 和 closed ,closed 狀態(tài)下,如果讀取開(kāi)門(mén)信號(hào),那么狀態(tài)就會(huì)切換為 open 。open 狀態(tài)下如果讀取關(guān)門(mén)信號(hào),狀態(tài)就會(huì)切換為 closed 。

狀態(tài)機(jī)的全稱是有限狀態(tài)自動(dòng)機(jī),自動(dòng)兩個(gè)字也是包含重要含義的。給定一個(gè)狀態(tài)機(jī),同時(shí)給定它的當(dāng)前狀態(tài)以及輸入,那么輸出狀態(tài)時(shí)可以明確的運(yùn)算出來(lái)的。例如對(duì)于自動(dòng)門(mén),給定初始狀態(tài) closed ,給定輸入“開(kāi)門(mén)”,那么下一個(gè)狀態(tài)時(shí)可以運(yùn)算出來(lái)的。

這樣狀態(tài)機(jī)的基本定義我們就介紹完畢了。重復(fù)一下:狀態(tài)機(jī)是有限狀態(tài)自動(dòng)機(jī)的簡(jiǎn)稱,是現(xiàn)實(shí)事物運(yùn)行規(guī)則抽象而成的一個(gè)數(shù)學(xué)模型。

1.2 四大概念

下面來(lái)給出狀態(tài)機(jī)的四大概念。

第一個(gè)是 State ,狀態(tài)。一個(gè)狀態(tài)機(jī)至少要包含兩個(gè)狀態(tài)。例如上面自動(dòng)門(mén)的例子,有 open 和 closed 兩個(gè)狀態(tài)。

第二個(gè)是 Event ,事件。事件就是執(zhí)行某個(gè)操作的觸發(fā)條件或者口令。對(duì)于自動(dòng)門(mén),“按下開(kāi)門(mén)按鈕”就是一個(gè)事件。

第三個(gè)是 Action ,動(dòng)作。事件發(fā)生以后要執(zhí)行動(dòng)作。例如事件是“按開(kāi)門(mén)按鈕”,動(dòng)作是“開(kāi)門(mén)”。編程的時(shí)候,一個(gè) Action一般就對(duì)應(yīng)一個(gè)函數(shù)。

第四個(gè)是 Transition ,變換。也就是從一個(gè)狀態(tài)變化為另一個(gè)狀態(tài)。例如“開(kāi)門(mén)過(guò)程”就是一個(gè)變換。

1.3 狀態(tài)機(jī)

有限狀態(tài)機(jī)(Finite-state machine,FSM),又稱有限狀態(tài)自動(dòng)機(jī),簡(jiǎn)稱狀態(tài)機(jī),是表示有限個(gè)狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動(dòng)作等行為的數(shù)學(xué)模型。

FSM是一種算法思想,簡(jiǎn)單而言,有限狀態(tài)機(jī)由一組狀態(tài)、一個(gè)初始狀態(tài)、輸入和根據(jù)輸入及現(xiàn)有狀態(tài)轉(zhuǎn)換為下一個(gè)狀態(tài)的轉(zhuǎn)換函數(shù)組成。

其作用主要是描述對(duì)象在它的生命周期內(nèi)所經(jīng)歷的狀態(tài)序列,以及如何響應(yīng)來(lái)自外界的各種事件。

Java指南:https://java-family.cn

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro

視頻教程:https://doc.iocoder.cn/video/

2、狀態(tài)機(jī)圖

做需求時(shí),需要了解以下六種元素:起始、終止、現(xiàn)態(tài)、次態(tài)(目標(biāo)狀態(tài))、動(dòng)作、條件,我們就可以完成一個(gè)狀態(tài)機(jī)圖了:

以訂單為例:以從待支付狀態(tài)轉(zhuǎn)換為待發(fā)貨狀態(tài)為例

ef0affbe-f84b-11ed-90ce-dac502259ad0.jpg

①現(xiàn)態(tài):是指當(dāng)前所處的狀態(tài)。待支付

②條件:又稱為“事件”,當(dāng)一個(gè)條件被滿足,將會(huì)觸發(fā)一個(gè)動(dòng)作,或者執(zhí)行一次狀態(tài)的遷移。支付事件

③動(dòng)作:條件滿足后執(zhí)行的動(dòng)作。動(dòng)作執(zhí)行完畢后,可以遷移到新的狀態(tài),也可以仍舊保持原狀態(tài)。動(dòng)作不是必需的,當(dāng)條件滿足后,也可以不執(zhí)行任何動(dòng)作,直接遷移到新?tīng)顟B(tài)。狀態(tài)轉(zhuǎn)換為待發(fā)貨

④次態(tài):條件滿足后要遷往的新?tīng)顟B(tài)?!按螒B(tài)”是相對(duì)于“現(xiàn)態(tài)”而言的,“次態(tài)”一旦被激活,就轉(zhuǎn)變成新的“現(xiàn)態(tài)”了。待發(fā)貨 注意事項(xiàng)

1、避免把某個(gè)“程序動(dòng)作”當(dāng)作是一種“狀態(tài)”來(lái)處理。那么如何區(qū)分“動(dòng)作”和“狀態(tài)”?“動(dòng)作”是不穩(wěn)定的,即使沒(méi)有條件的觸發(fā),“動(dòng)作”一旦執(zhí)行完畢就結(jié)束了;而“狀態(tài)”是相對(duì)穩(wěn)定的,如果沒(méi)有外部條件的觸發(fā),一個(gè)狀態(tài)會(huì)一直持續(xù)下去。關(guān)注工眾號(hào):碼猿技術(shù)專(zhuān)欄,回復(fù)關(guān)鍵詞:1111 獲取阿里內(nèi)部Java性能調(diào)優(yōu)手冊(cè)!

2、狀態(tài)劃分時(shí)漏掉一些狀態(tài),導(dǎo)致跳轉(zhuǎn)邏輯不完整。所以在設(shè)計(jì)狀態(tài)機(jī)時(shí),我們需要反復(fù)的查看設(shè)計(jì)的狀態(tài)圖或者狀態(tài)表,最終達(dá)到一種牢不可破的設(shè)計(jì)方案。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud

視頻教程:https://doc.iocoder.cn/video/

3、spring statemachine

3.1 狀態(tài)機(jī)spring statemachine 概述

Spring Statemachine是應(yīng)用程序開(kāi)發(fā)人員在Spring應(yīng)用程序中使用狀態(tài)機(jī)概念的框架

Spring Statemachine旨在提供以下功能:

易于使用的扁平單級(jí)狀態(tài)機(jī),用于簡(jiǎn)單的使用案例。

分層狀態(tài)機(jī)結(jié)構(gòu),以簡(jiǎn)化復(fù)雜的狀態(tài)配置。

狀態(tài)機(jī)區(qū)域提供更復(fù)雜的狀態(tài)配置。

使用觸發(fā)器,轉(zhuǎn)換,警衛(wèi)和操作。

鍵入安全配置適配器。

生成器模式,用于在Spring Application上下文之外使用的簡(jiǎn)單實(shí)例化通常用例的食譜

基于Zookeeper的分布式狀態(tài)機(jī)

狀態(tài)機(jī)事件監(jiān)聽(tīng)器。

UML Eclipse Papyrus建模。

將計(jì)算機(jī)配置存儲(chǔ)在永久存儲(chǔ)中。

Spring IOC集成將bean與狀態(tài)機(jī)關(guān)聯(lián)起來(lái)。

狀態(tài)機(jī)功能強(qiáng)大,因?yàn)樾袨槭冀K保證一致,使調(diào)試相對(duì)容易。這是因?yàn)椴僮饕?guī)則是在機(jī)器啟動(dòng)時(shí)寫(xiě)成的。這個(gè)想法是你的應(yīng)用程序可能存在于有限數(shù)量的狀態(tài)中,某些預(yù)定義的觸發(fā)器可以將你的應(yīng)用程序從一個(gè)狀態(tài)轉(zhuǎn)移到另一個(gè)狀態(tài)。此類(lèi)觸發(fā)器可以基于事件或計(jì)時(shí)器。

在應(yīng)用程序之外定義高級(jí)邏輯然后依靠狀態(tài)機(jī)來(lái)管理狀態(tài)要容易得多。您可以通過(guò)發(fā)送事件,偵聽(tīng)更改或僅請(qǐng)求當(dāng)前狀態(tài)來(lái)與狀態(tài)機(jī)進(jìn)行交互。

官網(wǎng):spring.io/projects/sp…

3.2 快速開(kāi)始

以訂單狀態(tài)扭轉(zhuǎn)的例子為例:

表結(jié)構(gòu)設(shè)計(jì)如下:

CREATETABLE`tb_order`(
`id`bigint(20)unsignedNOTNULLAUTO_INCREMENTCOMMENT'主鍵ID',
`order_code`varchar(128)COLLATEutf8mb4_binDEFAULTNULLCOMMENT'訂單編碼',
`status`smallint(3)DEFAULTNULLCOMMENT'訂單狀態(tài)',
`name`varchar(64)COLLATEutf8mb4_binDEFAULTNULLCOMMENT'訂單名稱',
`price`decimal(12,2)DEFAULTNULLCOMMENT'價(jià)格',
`delete_flag`tinyint(2)NOTNULLDEFAULT'0'COMMENT'刪除標(biāo)記,0未刪除1已刪除',
`create_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMPCOMMENT'創(chuàng)建時(shí)間',
`update_time`timestampNOTNULLDEFAULT'0000-00-000000'COMMENT'更新時(shí)間',
`create_user_code`varchar(32)COLLATEutf8mb4_binDEFAULTNULLCOMMENT'創(chuàng)建人',
`update_user_code`varchar(32)COLLATEutf8mb4_binDEFAULTNULLCOMMENT'更新人',
`version`int(11)NOTNULLDEFAULT'0'COMMENT'版本號(hào)',
`remark`varchar(64)COLLATEutf8mb4_binDEFAULTNULLCOMMENT'備注',
PRIMARYKEY(`id`)
)ENGINE=InnoDBAUTO_INCREMENT=6DEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_binCOMMENT='訂單表';

/*Dataforthetable`tb_order`*/

insertinto`tb_order`(`id`,`order_code`,`status`,`name`,`price`,`delete_flag`,`create_time`,`update_time`,`create_user_code`,`update_user_code`,`version`,`remark`)values
(2,'A111',1,'A','22.00',0,'2022-10-151611','2022-10-022114','zhangsan','zhangsan',0,NULL),
(3,'A111',1,'訂單A','22.00',0,'2022-10-022113','2022-10-022114','zhangsan','zhangsan',0,NULL),
(4,'A111',1,'訂單A','22.00',0,'2022-10-022113','2022-10-022114','zhangsan','zhangsan',0,NULL),
(5,'A111',1,'訂單A','22.00',0,'2022-10-030930','2022-10-022114','zhangsan','zhangsan',0,NULL);

1)引入依賴

 

org.springframework.statemachine
spring-statemachine-redis
1.2.9.RELEASE

 

org.springframework.statemachine
spring-statemachine-starter
2.0.1.RELEASE

2)定義狀態(tài)機(jī)狀態(tài)和事件

狀態(tài)枚舉:

/**
*author:芋道源碼
*/
publicenumOrderStatus{
//待支付,待發(fā)貨,待收貨,已完成
WAIT_PAYMENT(1,"待支付"),
WAIT_DELIVER(2,"待發(fā)貨"),
WAIT_RECEIVE(3,"待收貨"),
FINISH(4,"已完成");
privateIntegerkey;
privateStringdesc;
OrderStatus(Integerkey,Stringdesc){
this.key=key;
this.desc=desc;
}
publicIntegergetKey(){
returnkey;
}
publicStringgetDesc(){
returndesc;
}
publicstaticOrderStatusgetByKey(Integerkey){
for(OrderStatuse:values()){
if(e.getKey().equals(key)){
returne;
}
}
thrownewRuntimeException("enumnotexists.");
}
}

事件:

/**
*author:芋道源碼
*/
publicenumOrderStatusChangeEvent{
//支付,發(fā)貨,確認(rèn)收貨
PAYED,DELIVERY,RECEIVED;
}

3)定義狀態(tài)機(jī)規(guī)則和配置狀態(tài)機(jī)

@Configuration
@EnableStateMachine(name="orderStateMachine")
publicclassOrderStateMachineConfigextendsStateMachineConfigurerAdapter{
/**
*配置狀態(tài)
*
*@paramstates
*@throwsException
*/
publicvoidconfigure(StateMachineStateConfigurerstates)throwsException{
states
.withStates()
.initial(OrderStatus.WAIT_PAYMENT)
.states(EnumSet.allOf(OrderStatus.class));
}
/**
*配置狀態(tài)轉(zhuǎn)換事件關(guān)系
*
*@paramtransitions
*@throwsException
*/
publicvoidconfigure(StateMachineTransitionConfigurertransitions)throwsException{
transitions
//支付事件:待支付-》待發(fā)貨
.withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED)
.and()
//發(fā)貨事件:待發(fā)貨-》待收貨
.withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERY)
.and()
//收貨事件:待收貨-》已完成
.withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED);
}
}

配置持久化:

/**
*author:芋道源碼
*/
@Configuration
@Slf4j
publicclassPersist{
/**
*持久化到內(nèi)存map中
*
*@return
*/
@Bean(name="stateMachineMemPersister")
publicstaticStateMachinePersistergetPersister(){
returnnewDefaultStateMachinePersister(newStateMachinePersist(){
@Override
publicvoidwrite(StateMachineContextcontext,ObjectcontextObj)throwsException{
log.info("持久化狀態(tài)機(jī),context:{},contextObj:{}",JSON.toJSONString(context),JSON.toJSONString(contextObj));
map.put(contextObj,context);
}
@Override
publicStateMachineContextread(ObjectcontextObj)throwsException{
log.info("獲取狀態(tài)機(jī),contextObj:{}",JSON.toJSONString(contextObj));
StateMachineContextstateMachineContext=(StateMachineContext)map.get(contextObj);
log.info("獲取狀態(tài)機(jī)結(jié)果,stateMachineContext:{}",JSON.toJSONString(stateMachineContext));
returnstateMachineContext;
}
privateMapmap=newHashMap();
});
}

@Resource
privateRedisConnectionFactoryredisConnectionFactory;
/**
*持久化到redis中,在分布式系統(tǒng)中使用
*
*@return
*/
@Bean(name="stateMachineRedisPersister")
publicRedisStateMachinePersistergetRedisPersister(){
RedisStateMachineContextRepositoryrepository=newRedisStateMachineContextRepository<>(redisConnectionFactory);
RepositoryStateMachinePersistp=newRepositoryStateMachinePersist<>(repository);
returnnewRedisStateMachinePersister<>(p);
}
}

4)業(yè)務(wù)系統(tǒng)

controller:

/**
*author:芋道源碼
*/
@RestController
@RequestMapping("/order")
publicclassOrderController{
@Resource
privateOrderServiceorderService;
/**
*根據(jù)id查詢訂單
*
*@return
*/
@RequestMapping("/getById")
publicOrdergetById(@RequestParam("id")Longid){
//根據(jù)id查詢訂單
Orderorder=orderService.getById(id);
returnorder;
}
/**
*創(chuàng)建訂單
*
*@return
*/
@RequestMapping("/create")
publicStringcreate(@RequestBodyOrderorder){
//創(chuàng)建訂單
orderService.create(order);
return"sucess";
}
/**
*對(duì)訂單進(jìn)行支付
*
*@paramid
*@return
*/
@RequestMapping("/pay")
publicStringpay(@RequestParam("id")Longid){
//對(duì)訂單進(jìn)行支付
orderService.pay(id);
return"success";
}

/**
*對(duì)訂單進(jìn)行發(fā)貨
*
*@paramid
*@return
*/
@RequestMapping("/deliver")
publicStringdeliver(@RequestParam("id")Longid){
//對(duì)訂單進(jìn)行確認(rèn)收貨
orderService.deliver(id);
return"success";
}
/**
*對(duì)訂單進(jìn)行確認(rèn)收貨
*
*@paramid
*@return
*/
@RequestMapping("/receive")
publicStringreceive(@RequestParam("id")Longid){
//對(duì)訂單進(jìn)行確認(rèn)收貨
orderService.receive(id);
return"success";
}
}

servie:

/**
*author:芋道源碼
*/
@Service("orderService")
@Slf4j
publicclassOrderServiceImplextendsServiceImplimplementsOrderService{
@Resource
privateStateMachineorderStateMachine;
@Resource
privateStateMachinePersisterstateMachineMemPersister;
@Resource
privateOrderMapperorderMapper;
/**
*創(chuàng)建訂單
*
*@paramorder
*@return
*/
publicOrdercreate(Orderorder){
order.setStatus(OrderStatus.WAIT_PAYMENT.getKey());
orderMapper.insert(order);
returnorder;
}
/**
*對(duì)訂單進(jìn)行支付
*
*@paramid
*@return
*/
publicOrderpay(Longid){
Orderorder=orderMapper.selectById(id);
log.info("線程名稱:{},嘗試支付,訂單號(hào):{}",Thread.currentThread().getName(),id);
if(!sendEvent(OrderStatusChangeEvent.PAYED,order)){
log.error("線程名稱:{},支付失敗,狀態(tài)異常,訂單信息:{}",Thread.currentThread().getName(),order);
thrownewRuntimeException("支付失敗,訂單狀態(tài)異常");
}
returnorder;
}
/**
*對(duì)訂單進(jìn)行發(fā)貨
*
*@paramid
*@return
*/
publicOrderdeliver(Longid){
Orderorder=orderMapper.selectById(id);
log.info("線程名稱:{},嘗試發(fā)貨,訂單號(hào):{}",Thread.currentThread().getName(),id);
if(!sendEvent(OrderStatusChangeEvent.DELIVERY,order)){
log.error("線程名稱:{},發(fā)貨失敗,狀態(tài)異常,訂單信息:{}",Thread.currentThread().getName(),order);
thrownewRuntimeException("發(fā)貨失敗,訂單狀態(tài)異常");
}
returnorder;
}
/**
*對(duì)訂單進(jìn)行確認(rèn)收貨
*
*@paramid
*@return
*/
publicOrderreceive(Longid){
Orderorder=orderMapper.selectById(id);
log.info("線程名稱:{},嘗試收貨,訂單號(hào):{}",Thread.currentThread().getName(),id);
if(!sendEvent(OrderStatusChangeEvent.RECEIVED,order)){
log.error("線程名稱:{},收貨失敗,狀態(tài)異常,訂單信息:{}",Thread.currentThread().getName(),order);
thrownewRuntimeException("收貨失敗,訂單狀態(tài)異常");
}
returnorder;
}
/**
*發(fā)送訂單狀態(tài)轉(zhuǎn)換事件
*synchronized修飾保證這個(gè)方法是線程安全的
*
*@paramchangeEvent
*@paramorder
*@return
*/
privatesynchronizedbooleansendEvent(OrderStatusChangeEventchangeEvent,Orderorder){
booleanresult=false;
try{
//啟動(dòng)狀態(tài)機(jī)
orderStateMachine.start();
//嘗試恢復(fù)狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.restore(orderStateMachine,String.valueOf(order.getId()));
Messagemessage=MessageBuilder.withPayload(changeEvent).setHeader("order",order).build();
result=orderStateMachine.sendEvent(message);
//持久化狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.persist(orderStateMachine,String.valueOf(order.getId()));
}catch(Exceptione){
log.error("訂單操作失敗:{}",e);
}finally{
orderStateMachine.stop();
}
returnresult;
}
}

監(jiān)聽(tīng)狀態(tài)的變化:

/**
*author:芋道源碼
*/
@Component("orderStateListener")
@WithStateMachine(name="orderStateMachine")
@Slf4j
publicclassOrderStateListenerImpl{
@Resource
privateOrderMapperorderMapper;

@OnTransition(source="WAIT_PAYMENT",target="WAIT_DELIVER")
publicvoidpayTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("支付,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
//更新訂單
order.setStatus(OrderStatus.WAIT_DELIVER.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
}
@OnTransition(source="WAIT_DELIVER",target="WAIT_RECEIVE")
publicvoiddeliverTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("發(fā)貨,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
//更新訂單
order.setStatus(OrderStatus.WAIT_RECEIVE.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
}
@OnTransition(source="WAIT_RECEIVE",target="FINISH")
publicvoidreceiveTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("確認(rèn)收貨,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
//更新訂單
order.setStatus(OrderStatus.FINISH.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
}
}

3.3 測(cè)試驗(yàn)證

1)驗(yàn)證業(yè)務(wù)

新增一個(gè)訂單

http://localhost:8084/order/create

對(duì)訂單進(jìn)行支付

http://localhost:8084/order/pay?id=2

對(duì)訂單進(jìn)行發(fā)貨

http://localhost:8084/order/deliver?id=2

對(duì)訂單進(jìn)行確認(rèn)收貨

http://localhost:8084/order/receive?id=2

正常流程結(jié)束。如果對(duì)一個(gè)訂單進(jìn)行支付了,再次進(jìn)行支付,則會(huì)報(bào)錯(cuò):http://localhost:8084/order/pay?id=2

報(bào)錯(cuò)如下:

ef14c922-f84b-11ed-90ce-dac502259ad0.jpg

2)驗(yàn)證持久化

內(nèi)存

使用內(nèi)存持久化類(lèi)持久化:

/**
*author:芋道源碼
*/
@Resource
privateStateMachinePersisterstateMachineMemPersister;

/**
*發(fā)送訂單狀態(tài)轉(zhuǎn)換事件
*synchronized修飾保證這個(gè)方法是線程安全的
*
*@paramchangeEvent
*@paramorder
*@return
*/
privatesynchronizedbooleansendEvent(OrderStatusChangeEventchangeEvent,Orderorder){
booleanresult=false;
try{
//啟動(dòng)狀態(tài)機(jī)
orderStateMachine.start();
//嘗試恢復(fù)狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.restore(orderStateMachine,String.valueOf(order.getId()));
Messagemessage=MessageBuilder.withPayload(changeEvent).setHeader("order",order).build();
result=orderStateMachine.sendEvent(message);
//持久化狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.persist(orderStateMachine,String.valueOf(order.getId()));
}catch(Exceptione){
log.error("訂單操作失敗:{}",e);
}finally{
orderStateMachine.stop();
}
returnresult;
}

redis持久化

引入依賴:

 

org.springframework.statemachine
spring-statemachine-redis
1.2.9.RELEASE

配置yaml:

spring:
redis:
database:0
host:localhost
jedis:
pool:
max-active:8
max-idle:8
max-wait:''
min-idle:0
password:''
port:6379
timeout:0

使用redis持久化類(lèi)持久化:

/**
*author:芋道源碼
*/
@Resource
privateStateMachinePersisterstateMachineRedisPersister;

/**
*發(fā)送訂單狀態(tài)轉(zhuǎn)換事件
*synchronized修飾保證這個(gè)方法是線程安全的
*
*@paramchangeEvent
*@paramorder
*@return
*/
privatesynchronizedbooleansendEvent(OrderStatusChangeEventchangeEvent,Orderorder){
booleanresult=false;
try{
//啟動(dòng)狀態(tài)機(jī)
orderStateMachine.start();
//嘗試恢復(fù)狀態(tài)機(jī)狀態(tài)
stateMachineRedisPersister.restore(orderStateMachine,String.valueOf(order.getId()));
Messagemessage=MessageBuilder.withPayload(changeEvent).setHeader("order",order).build();
result=orderStateMachine.sendEvent(message);
//持久化狀態(tài)機(jī)狀態(tài)
stateMachineRedisPersister.persist(orderStateMachine,String.valueOf(order.getId()));
}catch(Exceptione){
log.error("訂單操作失敗:{}",e);
}finally{
orderStateMachine.stop();
}
returnresult;
}

3.4 狀態(tài)機(jī)存在的問(wèn)題

1)stateMachine無(wú)法拋出異常,異常會(huì)被狀態(tài)機(jī)給消化掉

問(wèn)題現(xiàn)象

從orderStateMachine.sendEvent(message);獲取的結(jié)果無(wú)法感知到。無(wú)論執(zhí)行正常還是拋出異常,都返回true。

@Resource
privateOrderMapperorderMapper;

@Resource
privateStateMachineorderStateMachine;

@OnTransition(source="WAIT_PAYMENT",target="WAIT_DELIVER")
@Transactional(rollbackFor=Exception.class)
publicvoidpayTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("支付,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
try{
//更新訂單
order.setStatus(OrderStatus.WAIT_DELIVER.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
//模擬異常
if(Objects.equals(order.getName(),"A")){
thrownewRuntimeException("執(zhí)行業(yè)務(wù)異常");
}
}catch(Exceptione){
//如果出現(xiàn)異常,記錄異常信息,拋出異常信息進(jìn)行回滾
log.error("payTransition出現(xiàn)異常:{}",e);
throwe;
}
}

監(jiān)聽(tīng)事件拋出異常,在發(fā)送事件中無(wú)法感知:

privatesynchronizedbooleansendEvent(OrderStatusChangeEventchangeEvent,Orderorder){
booleanresult=false;
try{
//啟動(dòng)狀態(tài)機(jī)
orderStateMachine.start();
//嘗試恢復(fù)狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.restore(orderStateMachine,String.valueOf(order.getId()));
Messagemessage=MessageBuilder.withPayload(changeEvent).setHeader("order",order).build();
//事件執(zhí)行異常了,依然返回true,無(wú)法感知異常
result=orderStateMachine.sendEvent(message);
if(result){
//持久化狀態(tài)機(jī)狀態(tài),如果根據(jù)true持久化,則會(huì)出現(xiàn)問(wèn)題
stateMachineMemPersister.persist(orderStateMachine,String.valueOf(order.getId()));
}
}catch(Exceptione){
log.error("訂單操作失敗:{}",e);
}finally{
orderStateMachine.stop();
}
returnresult;
}

調(diào)試發(fā)現(xiàn):發(fā)送事件和監(jiān)聽(tīng)事件是一個(gè)線程,發(fā)送事件的結(jié)果是在監(jiān)聽(tīng)操作執(zhí)行完之后才返回

ef1b945a-f84b-11ed-90ce-dac502259ad0.jpg

監(jiān)聽(tīng)線程:

ef278292-f84b-11ed-90ce-dac502259ad0.jpg

解決方案:自己保存異常到數(shù)據(jù)庫(kù)或者內(nèi)存中,進(jìn)行判斷

也可以通過(guò)接口:org.springframework.statemachine.StateMachine##getExtendedState

方法把執(zhí)行狀態(tài)放入這個(gè)變量中

publicinterfaceExtendedState{
MapgetVariables();
Tget(Objectvar1,Classvar2);
voidsetExtendedStateChangeListener(ExtendedState.ExtendedStateChangeListenervar1);
publicinterfaceExtendedStateChangeListener{
voidchanged(Objectvar1,Objectvar2);
}
}

org.springframework.statemachine.support.DefaultExtendedState##getVariables

privatefinalMapvariables;

publicDefaultExtendedState(){
this.variables=newObservableMap(newConcurrentHashMap(),newDefaultExtendedState.LocalMapChangeListener());
}

publicMapgetVariables(){
returnthis.variables;
}

改造監(jiān)聽(tīng)狀態(tài):把業(yè)務(wù)的執(zhí)行結(jié)果進(jìn)行保存,1成功,0失敗

@Resource
privateOrderMapperorderMapper;
@Resource
privateStateMachineorderStateMachine;

@OnTransition(source="WAIT_PAYMENT",target="WAIT_DELIVER")
@Transactional(rollbackFor=Exception.class)
publicvoidpayTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("支付,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
try{
//更新訂單
order.setStatus(OrderStatus.WAIT_DELIVER.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
//模擬異常
if(Objects.equals(order.getName(),"A")){
thrownewRuntimeException("執(zhí)行業(yè)務(wù)異常");
}
//成功則為1
orderStateMachine.getExtendedState().getVariables().put(CommonConstants.payTransition+order.getId(),1);
}catch(Exceptione){
//如果出現(xiàn)異常,則進(jìn)行回滾
log.error("payTransition出現(xiàn)異常:{}",e);
//將異常信息變量信息中,失敗則為0
orderStateMachine.getExtendedState().getVariables().put(CommonConstants.payTransition+order.getId(),0);
throwe;
}
}

發(fā)送事件改造:如果獲取到業(yè)務(wù)執(zhí)行異常,則返回失敗,不進(jìn)行狀態(tài)機(jī)持久化 com.zengqingfa.springboot.state.demo.service.impl.OrderServiceImpl##sendEvent

@Resource
privateStateMachineorderStateMachine;
@Resource
privateStateMachinePersisterstateMachineMemPersister;

/**
*發(fā)送訂單狀態(tài)轉(zhuǎn)換事件
*synchronized修飾保證這個(gè)方法是線程安全的
*
*@paramchangeEvent
*@paramorder
*@return
*/
privatesynchronizedbooleansendEvent(OrderStatusChangeEventchangeEvent,Orderorder){
booleanresult=false;
try{
//啟動(dòng)狀態(tài)機(jī)
orderStateMachine.start();
//嘗試恢復(fù)狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.restore(orderStateMachine,String.valueOf(order.getId()));
Messagemessage=MessageBuilder.withPayload(changeEvent).setHeader("order",order).build();
result=orderStateMachine.sendEvent(message);
if(!result){
returnfalse;
}
//獲取到監(jiān)聽(tīng)的結(jié)果信息
Integero=(Integer)orderStateMachine.getExtendedState().getVariables().get(CommonConstants.payTransition+order.getId());
//操作完成之后,刪除本次對(duì)應(yīng)的key信息
orderStateMachine.getExtendedState().getVariables().remove(CommonConstants.payTransition+order.getId());
//如果事務(wù)執(zhí)行成功,則持久化狀態(tài)機(jī)
if(Objects.equals(1,Integer.valueOf(o))){
//持久化狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.persist(orderStateMachine,String.valueOf(order.getId()));
}else{
//訂單執(zhí)行業(yè)務(wù)異常
returnfalse;
}
}catch(Exceptione){
log.error("訂單操作失敗:{}",e);
}finally{
orderStateMachine.stop();
}
returnresult;
}

代碼優(yōu)化

發(fā)送事件只針對(duì)了支付,如果是非支付事件呢?

//獲取到監(jiān)聽(tīng)的結(jié)果信息
Integero=(Integer)orderStateMachine.getExtendedState().getVariables().get(CommonConstants.payTransition+order.getId());

監(jiān)聽(tīng)設(shè)置狀態(tài)的代碼有重復(fù)代碼,需要進(jìn)行優(yōu)化,可使用aop

try{
//TODO其他業(yè)務(wù)
//成功則為1
orderStateMachine.getExtendedState().getVariables().put(CommonConstants.payTransition+order.getId(),1);
}catch(Exceptione){
//如果出現(xiàn)異常,則進(jìn)行回滾
log.error("payTransition出現(xiàn)異常:{}",e);
//將異常信息變量信息中,失敗則為0
orderStateMachine.getExtendedState().getVariables().put(CommonConstants.payTransition+order.getId(),0);
throwe;
}

常量類(lèi):

publicinterfaceCommonConstants{
StringorderHeader="order";
StringpayTransition="payTransition";
StringdeliverTransition="deliverTransition";
StringreceiveTransition="receiveTransition";
}

支付發(fā)送事件:com.zengqingfa.springboot.state.demo.service.impl.OrderServiceImpl##pay

@Resource
privateStateMachineorderStateMachine;
@Resource
privateStateMachinePersisterstateMachineMemPersister;
@Resource
privateOrderMapperorderMapper;

/**
*對(duì)訂單進(jìn)行支付
*
*@paramid
*@return
*/
publicOrderpay(Longid){
Orderorder=orderMapper.selectById(id);
log.info("線程名稱:{},嘗試支付,訂單號(hào):{}",Thread.currentThread().getName(),id);
if(!sendEvent(OrderStatusChangeEvent.PAYED,order,CommonConstants.payTransition)){
log.error("線程名稱:{},支付失敗,狀態(tài)異常,訂單信息:{}",Thread.currentThread().getName(),order);
thrownewRuntimeException("支付失敗,訂單狀態(tài)異常");
}
returnorder;
}

/**
*發(fā)送訂單狀態(tài)轉(zhuǎn)換事件
*synchronized修飾保證這個(gè)方法是線程安全的
*
*@paramchangeEvent
*@paramorder
*@return
*/
privatesynchronizedbooleansendEvent(OrderStatusChangeEventchangeEvent,Orderorder,Stringkey){
booleanresult=false;
try{
//啟動(dòng)狀態(tài)機(jī)
orderStateMachine.start();
//嘗試恢復(fù)狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.restore(orderStateMachine,String.valueOf(order.getId()));
Messagemessage=MessageBuilder.withPayload(changeEvent).setHeader("order",order).build();
result=orderStateMachine.sendEvent(message);
if(!result){
returnfalse;
}
//獲取到監(jiān)聽(tīng)的結(jié)果信息
Integero=(Integer)orderStateMachine.getExtendedState().getVariables().get(key+order.getId());
//操作完成之后,刪除本次對(duì)應(yīng)的key信息
orderStateMachine.getExtendedState().getVariables().remove(key+order.getId());
//如果事務(wù)執(zhí)行成功,則持久化狀態(tài)機(jī)
if(Objects.equals(1,Integer.valueOf(o))){
//持久化狀態(tài)機(jī)狀態(tài)
stateMachineMemPersister.persist(orderStateMachine,String.valueOf(order.getId()));
}else{
//訂單執(zhí)行業(yè)務(wù)異常
returnfalse;
}
}catch(Exceptione){
log.error("訂單操作失敗:{}",e);
}finally{
orderStateMachine.stop();
}
returnresult;
}

使用aop對(duì)監(jiān)聽(tīng)事件切面,把業(yè)務(wù)執(zhí)行結(jié)果封裝到狀態(tài)機(jī)的變量中,注解:

@Retention(RetentionPolicy.RUNTIME)
public@interfaceLogResult{
/**
*執(zhí)行的業(yè)務(wù)key
*
*@returnString
*/
Stringkey();
}

切面:

@Component
@Aspect
@Slf4j
publicclassLogResultAspect{

//攔截LogHistory注解
@Pointcut("@annotation(com.zengqingfa.springboot.state.demo.aop.annotation.LogResult)")
privatevoidlogResultPointCut(){
//logResultPointCut日志注解切點(diǎn)
}
@Resource
privateStateMachineorderStateMachine;

@Around("logResultPointCut()")
publicObjectlogResultAround(ProceedingJoinPointpjp)throwsThrowable{
//獲取參數(shù)
Object[]args=pjp.getArgs();
log.info("參數(shù)args:{}",args);
Messagemessage=(Message)args[0];
Orderorder=(Order)message.getHeaders().get("order");
//獲取方法
Methodmethod=((MethodSignature)pjp.getSignature()).getMethod();
//獲取LogHistory注解
LogResultlogResult=method.getAnnotation(LogResult.class);
Stringkey=logResult.key();
ObjectreturnVal=null;
try{
//執(zhí)行方法
returnVal=pjp.proceed();
//如果業(yè)務(wù)執(zhí)行正常,則保存信息
//成功則為1
orderStateMachine.getExtendedState().getVariables().put(key+order.getId(),1);
}catch(Throwablee){
log.error("e:{}",e.getMessage());
//如果業(yè)務(wù)執(zhí)行異常,則保存信息
//將異常信息變量信息中,失敗則為0
orderStateMachine.getExtendedState().getVariables().put(key+order.getId(),0);
throwe;
}
returnreturnVal;
}
}

監(jiān)聽(tīng)類(lèi)使用注解:

@Component("orderStateListener")
@WithStateMachine(name="orderStateMachine")
@Slf4j
publicclassOrderStateListenerImpl{
@Resource
privateOrderMapperorderMapper;

@OnTransition(source="WAIT_PAYMENT",target="WAIT_DELIVER")
@Transactional(rollbackFor=Exception.class)
@LogResult(key=CommonConstants.payTransition)
publicvoidpayTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("支付,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
//更新訂單
order.setStatus(OrderStatus.WAIT_DELIVER.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
//模擬異常
if(Objects.equals(order.getName(),"A")){
thrownewRuntimeException("執(zhí)行業(yè)務(wù)異常");
}
}
@OnTransition(source="WAIT_DELIVER",target="WAIT_RECEIVE")
@LogResult(key=CommonConstants.deliverTransition)
publicvoiddeliverTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("發(fā)貨,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
//更新訂單
order.setStatus(OrderStatus.WAIT_RECEIVE.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
}
@OnTransition(source="WAIT_RECEIVE",target="FINISH")
@LogResult(key=CommonConstants.receiveTransition)
publicvoidreceiveTransition(Messagemessage){
Orderorder=(Order)message.getHeaders().get("order");
log.info("確認(rèn)收貨,狀態(tài)機(jī)反饋信息:{}",message.getHeaders().toString());
//更新訂單
order.setStatus(OrderStatus.FINISH.getKey());
orderMapper.updateById(order);
//TODO其他業(yè)務(wù)
}
}
審核編輯:彭靜
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3689

    瀏覽量

    95252
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    15078
  • 數(shù)學(xué)模型
    +關(guān)注

    關(guān)注

    0

    文章

    83

    瀏覽量

    12262
  • 自動(dòng)機(jī)
    +關(guān)注

    關(guān)注

    1

    文章

    28

    瀏覽量

    9492

原文標(biāo)題:項(xiàng)目終于用上了Spring狀態(tài)機(jī),非常優(yōu)雅!

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Spring狀態(tài)機(jī)的實(shí)現(xiàn)原理和使用方法

    說(shuō)起 Spring 狀態(tài)機(jī),大家很容易聯(lián)想到這個(gè)狀態(tài)機(jī)和設(shè)計(jì)模式中狀態(tài)模式的區(qū)別是啥呢?沒(méi)錯(cuò),Spring
    的頭像 發(fā)表于 12-26 09:39 ?2698次閱讀
    <b class='flag-5'>Spring</b><b class='flag-5'>狀態(tài)機(jī)</b>的實(shí)現(xiàn)原理和使用方法

    Verilog狀態(tài)機(jī)+設(shè)計(jì)實(shí)例

    在verilog中狀態(tài)機(jī)的一種很常用的邏輯結(jié)構(gòu),學(xué)習(xí)和理解狀態(tài)機(jī)的運(yùn)行規(guī)律能夠幫助我們更好地書(shū)寫(xiě)代碼,同時(shí)作為一種思想方法,在別的代碼設(shè)計(jì)中也會(huì)有所幫助。 一、簡(jiǎn)介 在使用過(guò)程中我們常說(shuō)
    的頭像 發(fā)表于 02-12 19:07 ?5458次閱讀
    Verilog<b class='flag-5'>狀態(tài)機(jī)</b>+設(shè)計(jì)實(shí)例

    玩轉(zhuǎn)Spring狀態(tài)機(jī)

    說(shuō)起Spring狀態(tài)機(jī),大家很容易聯(lián)想到這個(gè)狀態(tài)機(jī)和設(shè)計(jì)模式中狀態(tài)模式的區(qū)別是啥呢?沒(méi)錯(cuò),Spring
    的頭像 發(fā)表于 06-25 14:21 ?1312次閱讀
    玩轉(zhuǎn)<b class='flag-5'>Spring</b><b class='flag-5'>狀態(tài)機(jī)</b>

    如何寫(xiě)好狀態(tài)機(jī)

    如何寫(xiě)好狀態(tài)機(jī):狀態(tài)機(jī)是邏輯設(shè)計(jì)的重要內(nèi)容,狀態(tài)機(jī)的設(shè)計(jì)水平直接反應(yīng)工程師的邏輯功底,所以許多公司的硬件和邏輯工程師面試中,狀態(tài)機(jī)設(shè)計(jì)幾乎是必選題目。本章在引入
    發(fā)表于 06-14 19:24 ?97次下載

    狀態(tài)機(jī)舉例

    狀態(tài)機(jī)舉例 你可以指定狀態(tài)寄存器和狀態(tài)機(jī)狀態(tài)。以下是一個(gè)有四種狀態(tài)的普通狀態(tài)機(jī)。 // Th
    發(fā)表于 03-28 15:18 ?1096次閱讀

    狀態(tài)機(jī)代碼生成工具

    狀態(tài)機(jī)代碼生成工具狀態(tài)機(jī)代碼生成工具狀態(tài)機(jī)代碼生成工具狀態(tài)機(jī)代碼生成工具
    發(fā)表于 11-19 15:12 ?9次下載

    狀態(tài)機(jī)原理及用法

    狀態(tài)機(jī)原理及用法狀態(tài)機(jī)原理及用法狀態(tài)機(jī)原理及用法
    發(fā)表于 03-15 15:25 ?0次下載

    簡(jiǎn)述使用QII狀態(tài)機(jī)向?qū)绾蝿?chuàng)建一個(gè)狀態(tài)機(jī)

    如何使用QII狀態(tài)機(jī)向?qū)?chuàng)建一個(gè)狀態(tài)機(jī)
    的頭像 發(fā)表于 06-20 00:11 ?4570次閱讀
    簡(jiǎn)述使用QII<b class='flag-5'>狀態(tài)機(jī)</b>向?qū)绾蝿?chuàng)建一個(gè)<b class='flag-5'>狀態(tài)機(jī)</b>

    狀態(tài)機(jī)概述 如何理解狀態(tài)機(jī)

    本篇文章包括狀態(tài)機(jī)的基本概述以及通過(guò)簡(jiǎn)單的實(shí)例理解狀態(tài)機(jī)
    的頭像 發(fā)表于 01-02 18:03 ?1.1w次閱讀
    <b class='flag-5'>狀態(tài)機(jī)</b>概述  如何理解<b class='flag-5'>狀態(tài)機(jī)</b>

    什么是狀態(tài)機(jī) 狀態(tài)機(jī)的描述三種方法

    狀態(tài)機(jī) 1、狀態(tài)機(jī)是許多數(shù)字系統(tǒng)的核心部件,是一類(lèi)重要的時(shí)序邏輯電路。通常包括三個(gè)部分:一是下一個(gè)狀態(tài)的邏輯電路,二是存儲(chǔ)狀態(tài)機(jī)當(dāng)前狀態(tài)的時(shí)
    的頭像 發(fā)表于 11-16 17:39 ?2.7w次閱讀

    FPGA:狀態(tài)機(jī)簡(jiǎn)述

    本文目錄 前言 狀態(tài)機(jī)簡(jiǎn)介 狀態(tài)機(jī)分類(lèi) Mealy 型狀態(tài)機(jī) Moore 型狀態(tài)機(jī) 狀態(tài)機(jī)描述 一段式
    的頭像 發(fā)表于 11-05 17:58 ?8052次閱讀
    FPGA:<b class='flag-5'>狀態(tài)機(jī)</b>簡(jiǎn)述

    什么是狀態(tài)機(jī)狀態(tài)機(jī)5要素

    等。 本文來(lái)說(shuō)一下狀態(tài)機(jī)編程。 什么是狀態(tài)機(jī)狀態(tài)機(jī)(state machine)有5個(gè)要素: 狀態(tài)(state) 遷移(transition) 事件(event) 動(dòng)作(actio
    的頭像 發(fā)表于 07-27 11:23 ?2.1w次閱讀
    什么是<b class='flag-5'>狀態(tài)機(jī)</b>?<b class='flag-5'>狀態(tài)機(jī)</b>5要素

    狀態(tài)模式(狀態(tài)機(jī))

    以前寫(xiě)狀態(tài)機(jī),比較常用的方式是用 if-else 或 switch-case,高級(jí)的一點(diǎn)是函數(shù)指針列表。最近,看了一文章《c語(yǔ)言設(shè)計(jì)模式–狀態(tài)模式(狀態(tài)機(jī))》(來(lái)源:embed linux
    發(fā)表于 12-16 16:53 ?9次下載
    <b class='flag-5'>狀態(tài)</b>模式(<b class='flag-5'>狀態(tài)機(jī)</b>)

    labview狀態(tài)機(jī)分享

    labview狀態(tài)機(jī)
    發(fā)表于 10-31 15:50 ?18次下載

    什么是狀態(tài)機(jī)?狀態(tài)機(jī)的種類(lèi)與實(shí)現(xiàn)

    狀態(tài)機(jī),又稱有限狀態(tài)機(jī)(Finite State Machine,F(xiàn)SM)或米利狀態(tài)機(jī)(Mealy Machine),是一種描述系統(tǒng)狀態(tài)變化的模型。在芯片設(shè)計(jì)中,
    的頭像 發(fā)表于 10-19 10:27 ?1.2w次閱讀