多线程环境中的弹簧状态机

时间:2016-05-06 08:30:15

标签: java spring multithreading spring-statemachine

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

  • 每个状态机只有一次状态上下文吗?
  • 传递给状态机的事件是否以阻塞方式运行?是否可以使它们并行运行,例如,每次触发事件时都提供新的状态机?

这是我的代码:

配置状态和转换:

@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);

1 个答案:

答案 0 :(得分:2)

是的,默认行为是阻止的,因为基础TaskExecutorSyncTaskExecutor。这可以通过文档中提到的common config进行更改。另请参阅tasks recipe默认情况下使用ThreadPoolTaskExecutor执行并行区域。

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