From 5fed1bbf190a156fd4c812f0f25e1a6e3ce528d0 Mon Sep 17 00:00:00 2001 From: SerLiunx-ctrl <17689543@qq.com> Date: Tue, 31 Dec 2024 09:21:03 +0800 Subject: [PATCH] =?UTF-8?q?change:=20=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= =?UTF-8?q?=E3=80=81=E5=AE=9A=E5=90=91=E5=88=87=E6=8D=A2=E6=97=B6=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E5=BD=93=E5=89=8D=E7=8A=B6=E6=80=81.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../machine/StandardStateMachine.java | 8 ++++++++ .../statemanagement/machine/StateMachine.java | 11 +++++++++-- .../machine/StateMachineBuilder.java | 1 - .../machine/handler/StateHandlerProcessParams.java | 2 -- .../manager/AbstractStateManager.java | 6 +++++- .../manager/DefaultUnidirectionalStateManager.java | 13 ++++++++++--- .../statemanagement/manager/StateManager.java | 2 -- .../com/serliunx/statemanagement/MachineTest.java | 11 +++++++---- .../com/serliunx/statemanagement/ManagerTest.java | 7 +++++++ 9 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java index 80e2faf..3972c1c 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StandardStateMachine.java @@ -149,8 +149,16 @@ public class StandardStateMachine extends AbstractStateManager implements @Override public boolean switchTo(S state) { + int i = indexOf(state); + if (i == -1 || i == currentIndex()) { + return false; + } try { writeLock.lock(); + // 重新检查 + if (i == currentIndex()) { + return false; + } S oldState = get(); boolean result = super.switchTo(state); if (result) { diff --git a/src/main/java/com/serliunx/statemanagement/machine/StateMachine.java b/src/main/java/com/serliunx/statemanagement/machine/StateMachine.java index 471ba41..16f09d8 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StateMachine.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StateMachine.java @@ -11,7 +11,7 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager; *
  • 切出指定状态时触发 (离开事件) *
  • 从A切换到B状态时触发 (交换事件) *

    - * 推荐使用{@link StateMachineBuilder} 来构建状态机. + * 请使用{@link StateMachineBuilder} 来构建状态机. * * @author SerLiunx * @version 1.0.0 @@ -22,5 +22,12 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager; */ public interface StateMachine extends BidirectionalStateManager { - + /** + * 切换到指定状态 + *

  • 在使用状态机的情况, 仅切换成功才会触发注册的各种事件. + * + * @param state 新的状态 + * @return 切换成功返回真, 否则返回假 + */ + boolean switchTo(S state); } diff --git a/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java b/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java index 9328444..a5bf711 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java +++ b/src/main/java/com/serliunx/statemanagement/machine/StateMachineBuilder.java @@ -2,7 +2,6 @@ package com.serliunx.statemanagement.machine; import com.serliunx.statemanagement.machine.handler.StateHandler; import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper; -import com.serliunx.statemanagement.manager.BidirectionalStateManager; import java.util.*; import java.util.concurrent.Executor; diff --git a/src/main/java/com/serliunx/statemanagement/machine/handler/StateHandlerProcessParams.java b/src/main/java/com/serliunx/statemanagement/machine/handler/StateHandlerProcessParams.java index f3e8677..9f1c2bb 100644 --- a/src/main/java/com/serliunx/statemanagement/machine/handler/StateHandlerProcessParams.java +++ b/src/main/java/com/serliunx/statemanagement/machine/handler/StateHandlerProcessParams.java @@ -1,7 +1,5 @@ package com.serliunx.statemanagement.machine.handler; -import com.serliunx.statemanagement.manager.BidirectionalStateManager; - /** * 状态处理器入参 *

    diff --git a/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java b/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java index c398981..bbd99ee 100644 --- a/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java +++ b/src/main/java/com/serliunx/statemanagement/manager/AbstractStateManager.java @@ -74,11 +74,15 @@ public abstract class AbstractStateManager implements StateManager { @Override public boolean switchTo(S state) { int i = indexOf(state); - if (i == -1) { + if (i == -1 || i == index) { return false; } try { writeLock.lock(); + // 重新检查 + if (i == index) { + return false; + } index = i; } finally { writeLock.unlock(); diff --git a/src/main/java/com/serliunx/statemanagement/manager/DefaultUnidirectionalStateManager.java b/src/main/java/com/serliunx/statemanagement/manager/DefaultUnidirectionalStateManager.java index c93bf0d..94c4680 100644 --- a/src/main/java/com/serliunx/statemanagement/manager/DefaultUnidirectionalStateManager.java +++ b/src/main/java/com/serliunx/statemanagement/manager/DefaultUnidirectionalStateManager.java @@ -61,11 +61,18 @@ public class DefaultUnidirectionalStateManager extends AbstractStateManager diff --git a/src/test/java/com/serliunx/statemanagement/MachineTest.java b/src/test/java/com/serliunx/statemanagement/MachineTest.java index 2330450..7f15600 100644 --- a/src/test/java/com/serliunx/statemanagement/MachineTest.java +++ b/src/test/java/com/serliunx/statemanagement/MachineTest.java @@ -22,20 +22,23 @@ public class MachineTest { public void testStandardStateMachine() { StateMachine stateMachine = StateMachineBuilder.from(PrinterState.class) .async(false) + .states(PrinterState.values()) + .executor(Executors.newFixedThreadPool(16)) .whenLeave(PrinterState.PRINTING, h -> { System.out.println(Thread.currentThread().getName() + ": leave PRINTING"); }) - .states(PrinterState.values()) - .executor(Executors.newFixedThreadPool(16)) .whenEntry(PrinterState.SCANNING, h -> { System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo()); - }, false) + }) .whenEntry(PrinterState.PRINTING, h -> { System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo()); - }, false, Executors.newFixedThreadPool(1)) + }) .exchange(PrinterState.STOPPED, PrinterState.IDLE, h -> { System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo()); }) .build(); + + stateMachine.switchTo(PrinterState.PRINTING); + stateMachine.switchNext(); } } diff --git a/src/test/java/com/serliunx/statemanagement/ManagerTest.java b/src/test/java/com/serliunx/statemanagement/ManagerTest.java index ee8e885..134b776 100644 --- a/src/test/java/com/serliunx/statemanagement/ManagerTest.java +++ b/src/test/java/com/serliunx/statemanagement/ManagerTest.java @@ -1,5 +1,8 @@ package com.serliunx.statemanagement; +import com.serliunx.statemanagement.manager.DefaultUnidirectionalStateManager; +import com.serliunx.statemanagement.manager.UnidirectionalStateManager; +import com.serliunx.statemanagement.support.PrinterState; import lombok.extern.slf4j.Slf4j; import org.junit.Test; @@ -15,6 +18,10 @@ public class ManagerTest { @Test public void testUnidirectionalStateManager() { + UnidirectionalStateManager unidirectionalStateManager = + new DefaultUnidirectionalStateManager<>(PrinterState.values()); + System.out.println(unidirectionalStateManager.switchTo(PrinterState.IDLE)); + System.out.println(unidirectionalStateManager.switchTo(PrinterState.SCANNING)); } }