spring 多线程环境下的状态机

spring state machine in multi threaded environment

我们刚刚开始使用 spring 状态机。有几个问题:

这是我的代码:

配置状态和转换:

@Override
public void configure(
        StateMachineTransitionConfigurer<WorkFlowStates, WorkFlowEvent> transitions)
                throws Exception {
    transitions
    .withExternal()
    .source(WorkFlowStates.ready)
    .target(WorkFlowStates.l1Creation)
    .event(WorkFlowEvent.createWorkItem)
    .action(workFlowCreator.createL1())

在状态转换期间提供操作:

public Action<WorkFlowStates, WorkFlowEvent> createL3() {
    return new Action<WorkFlowStates, WorkFlowEvent>() {

        public void execute(StateContext<WorkFlowStates, WorkFlowEvent> context) {
            System.out.println("l3 creation in action");
            Map<Object, Object> variables = context.getExtendedState().getVariables();
            Integer counter = (Integer)variables.get("counter");
            if(counter == null) counter = 1;
            else counter = counter+1;
            variables.put("counter", counter);
            System.out.println("Counter is "+counter);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            variables.put(Level.l3, WorkItemFactory.createFailureL1L2L3WorkItem());
            variables.put("level", Level.l3);
            System.out.println("l3 created");
        }
    };
}

任务执行者:

public void configure(StateMachineConfigurationConfigurer<WorkFlowStates, 
WorkFlowEvent>config)
                throws Exception {
    config
    .withConfiguration()
    .autoStartup(true)
    .taskExecutor(taskExecutor())
    .listener(new WorkFlowStateMachineListener()); 
}

@Bean(name = StateMachineSystemConstants.TASK_EXECUTOR_BEAN_NAME)
public TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.afterPropertiesSet();
    taskExecutor.setCorePoolSize(5);
    return taskExecutor;
}

并将事件传递给状态机:

StateMachine<WorkFlowStates, WorkFlowEvent> stateMachine = 
    context.getBean(StateMachine.class);

    stateMachine.sendEvent(WorkFlowEvent.createWorkItem);
    stateMachine.sendEvent(WorkFlowEvent.createWorkItem);

是的,默认行为是阻塞,因为底层 TaskExecutorSyncTaskExecutor。这可以通过 common config as mentioned in docs. Also see tasks recipe 更改,其中 ThreadPoolTaskExecutor 默认用于并行执行区域。

当远离阻塞机器时,您需要注意机器的工作方式以及它何时准备好处理进一步的事件,因为机器可能会处于事件被丢弃的状态。这通常是您可能需要开始添加延迟事件的时间,以便机器将来可以在更合适的时间处理这些事件。