java - fork 并加入 : a problem with parallel execution of two regions in spring state machine

标签 java fork-join spring-statemachine

我尝试使用“fork/join”结构在状态“S2”的区域并行执行状态机。状态机的配置基于 uml model . 我对这两个区域的并行工作有疑问。 首先,状态机经过状态 S20 到 S23,然后经过状态 S30 到 S33。

问题出在哪里? 预先感谢您的帮助。

这是我的状态机配置:

@Slf4j
@Configuration
@EnableStateMachine
public class StateMachineConfig extends StateMachineConfigurerAdapter<String, String> {

    @Override
    public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
        model
                .withModel()
                .factory(modelFactory());
    }

    @Bean
    public StateMachineModelFactory<String, String> modelFactory() {
        Resource model = new ClassPathResource("/uml/simple-forkjoin.uml");
        return new UmlStateMachineModelFactory(model);
    }


     @Override public void configure(StateMachineConfigurationConfigurer<String, String> config) throws Exception {
     config
     .withConfiguration()
     .listener(new StateMachineListener())
     .autoStartup(true);
     }
}

表示状态的示例类:

@Slf4j
@WithStateMachine
public class S22 {


    @OnTransition(target = "S22")
    public void onTransition(StateContext<String, String> stateContext) {
        log.info(Colours.ANSI_BLUE + "target = \"S22\", getState().getId(): "
                + stateContext.getStateMachine().getState().getId()
                + Colours.ANSI_RESET);
        Sleep.sleep(1000);
    }

    @OnStateChanged(target = "S22")
    public void onStateChanged(StateContext<String, String> stateContext) {
        log.debug(Colours.B_HI_ANSI_GREEN + "S22 EXPECTS_ORDERS stateChanged :: Current state ID :: {}",
                stateContext.getStateMachine().getState().getId() + Colours.ANSI_RESET);
        Sleep.sleep(1000);
    }
}

日志:

2019-03-21 12:25:01.746  INFO 7648 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
2019-03-21 12:25:01.780  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S0
2019-03-21 12:25:01.788  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S0          : target = "S0, getState().getId(): SI
2019-03-21 12:25:01.791 DEBUG 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S0          : S0 EXPECTS_ORDERS stateChanged :: Current state ID :: S0
2019-03-21 12:25:01.791  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : state changed from: SI to S0
2019-03-21 12:25:01.791  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S1
2019-03-21 12:25:01.792  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S1          : target = "S1", getState().getId(): S0
2019-03-21 12:25:01.794  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S21
2019-03-21 12:25:01.794  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S21         : target = "S21", getState().getId(): S2
2019-03-21 12:25:02.795  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S22
2019-03-21 12:25:02.797  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S22         : target = "S22", getState().getId(): S2
2019-03-21 12:25:03.799  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S23
2019-03-21 12:25:03.801  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S23         : target = "S23", getState().getId(): S2
2019-03-21 12:25:04.803  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : state changed from: S22 to S23
2019-03-21 12:25:04.803  INFO 7648 --- [nio-8080-exec-2] o.s.s.support.LifecycleObjectSupport     : started org.springframework.statemachine.support.DefaultStateMachineExecutor@76b2b847
2019-03-21 12:25:04.803  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : State machine started :: S2
2019-03-21 12:25:04.804  INFO 7648 --- [nio-8080-exec-2] o.s.s.support.LifecycleObjectSupport     : started S23 S22 S20 S21  / S23 / uuid=51391415-d1f5-440f-9c8e-677c00bcdd50 / id=null
2019-03-21 12:25:04.805 DEBUG 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S22         : S22 EXPECTS_ORDERS stateChanged :: Current state ID :: S2
2019-03-21 12:25:05.806  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : state changed from: S21 to S22
2019-03-21 12:25:05.806 DEBUG 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S21         : S21 EXPECTS_ORDERS stateChanged :: Current state ID :: S2
2019-03-21 12:25:06.807  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : state changed from: S20 to S21
2019-03-21 12:25:06.808 DEBUG 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S20         : S20 EXPECTS_ORDERS stateChanged :: Current state ID :: S2
2019-03-21 12:25:07.809  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : state changed from: null to S20
2019-03-21 12:25:07.809  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S31
2019-03-21 12:25:07.810  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S31         : target = "S31", getState().getId(): S2
2019-03-21 12:25:08.211  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S32
2019-03-21 12:25:08.212  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S32         : target = "S32", getState().getId(): S2
2019-03-21 12:25:08.613  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S33
2019-03-21 12:25:08.614  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S33         : target = "S33", getState().getId(): S2
2019-03-21 12:25:09.015  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S3
2019-03-21 12:25:09.016  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S3          : target = "S3", getState().getId(): S2
2019-03-21 12:25:09.016  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : transition started! target state: S3
2019-03-21 12:25:09.017  INFO 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S3          : target = "S3", getState().getId(): S2
2019-03-21 12:25:09.018  INFO 7648 --- [nio-8080-exec-2] o.s.s.support.LifecycleObjectSupport     : stopped org.springframework.statemachine.support.DefaultStateMachineExecutor@76b2b847
2019-03-21 12:25:09.018  INFO 7648 --- [nio-8080-exec-2] o.s.s.support.LifecycleObjectSupport     : stopped S23 S22 S20 S21  /  / uuid=51391415-d1f5-440f-9c8e-677c00bcdd50 / id=null
2019-03-21 12:25:09.019 DEBUG 7648 --- [nio-8080-exec-2] com.fj.forkJointest.forkJoin.S4          : S4 EXPECTS_ORDERS stateChanged :: Current state ID :: S4
2019-03-21 12:25:09.020  INFO 7648 --- [nio-8080-exec-2] c.f.f.config.StateMachineListener        : state changed from: S2 to S4

This is my github project

最佳答案

Spring 状态机使用 TaskExecutor对于区域执行,默认情况下它是同步的。要实现异步执行,您需要覆盖默认任务执行器。

您可以通过多种方式完成:

使用 StateMachineConfigurationConfigurer :

@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
    config
        .withConfiguration()
            //other configs
            .taskExecutor(myAsyncTaskExecutor())
}

public TaskExecutor myAsyncTaskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.setCorePoolSize(5);
    return taskExecutor;
}

或者简单地声明一个 bean,它将自动从 SM 中获取:

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

关于java - fork 并加入 : a problem with parallel execution of two regions in spring state machine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55280364/

相关文章:

java - 如何访问 Spring StateMachine 配置数据

java - 如何通过 Java 应用程序将查询结果从 MySQL 导出到 PowerPoint?

angular - 在 Angular 中进行嵌套 API 调用

java - 嵌套 session /事务中的 Transaction.rollback 会发生什么?

java - 并行对两个数组的每个元素求和

json - TypeScript 在对象数组上使用 forkJoin

java - 多线程环境下的Spring状态机

java - 用于管理 JPA 实体的 Spring 状态机

java - Android获取经纬度的方法

java - URL 类中 setURLStreamHandlerFactory 的用途