feat: 新增并发型状态机(基于CAS实现, 未完成).
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
package com.serliunx.statemanagement.machine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2025/2/6
|
||||||
|
*/
|
||||||
|
public interface ConcurrentStateMachine<S> extends StateMachine<S> {
|
||||||
|
|
||||||
|
boolean compareAndSet(S expectedValue, S newValue);
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package com.serliunx.statemanagement.machine;
|
||||||
|
|
||||||
|
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2025/2/6
|
||||||
|
*/
|
||||||
|
public class DefaultConcurrentStateMachine<S> extends AbstractStateMachine<S> implements ConcurrentStateMachine<S> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前状态
|
||||||
|
*/
|
||||||
|
private final AtomicInteger index = new AtomicInteger(0);
|
||||||
|
|
||||||
|
DefaultConcurrentStateMachine(List<S> stateList,
|
||||||
|
Map<S, List<StateHandlerWrapper<S>>> entryHandlers,
|
||||||
|
Map<S, List<StateHandlerWrapper<S>>> leaveHandlers,
|
||||||
|
Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers,
|
||||||
|
Map<Object, List<Consumer<StateMachine<S>>>> eventRegistries,
|
||||||
|
Executor executor,
|
||||||
|
Boolean async) {
|
||||||
|
super(stateList, entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean compareAndSet(S expectedValue, S newValue) {
|
||||||
|
int current = indexOf(expectedValue);
|
||||||
|
int newIndex = indexOf(newValue);
|
||||||
|
if (current == -1 || newIndex == -1)
|
||||||
|
return false;
|
||||||
|
return index.compareAndSet(current, newIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用CAS不断尝试将当前状态重置回默认值(0)
|
||||||
|
*
|
||||||
|
* @param invokeHandlers 是否唤醒状态处理器
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void reset(boolean invokeHandlers) {
|
||||||
|
if (isDefault())
|
||||||
|
return;
|
||||||
|
exchangeToTarget(0);
|
||||||
|
// TODO invokeHandlers
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean switchTo(S state, boolean invokeHandlers) {
|
||||||
|
int i = indexOf(state);
|
||||||
|
if (i == -1 ||
|
||||||
|
i == index.get()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
exchangeToTarget(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S switchPrevAndGet(boolean invokeHandlers) {
|
||||||
|
S oldState = get(index.get());
|
||||||
|
|
||||||
|
S newState = get(index.get());
|
||||||
|
if (invokeHandlers)
|
||||||
|
invokeHandlers(oldState, newState);
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S getAndSwitchPrev(boolean invokeHandlers) {
|
||||||
|
return super.getAndSwitchPrev(invokeHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void switchPrev(boolean invokeHandlers) {
|
||||||
|
super.switchPrev(invokeHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S switchNextAndGet(boolean invokeHandlers) {
|
||||||
|
return super.switchNextAndGet(invokeHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public S getAndSwitchNext(boolean invokeHandlers) {
|
||||||
|
return super.getAndSwitchNext(invokeHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void switchNext(boolean invokeHandlers) {
|
||||||
|
super.switchNext(invokeHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publish(Object event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为默认状态
|
||||||
|
*/
|
||||||
|
private boolean isDefault() {
|
||||||
|
return index.get() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动下标至上一个状态
|
||||||
|
*/
|
||||||
|
public void exchangeToPrev() {
|
||||||
|
final int size = size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换到指定状态值
|
||||||
|
* <li> 使用CAS一直尝试, 直到成功
|
||||||
|
*
|
||||||
|
* @param target 目标值
|
||||||
|
*/
|
||||||
|
private void exchangeToTarget(int target) {
|
||||||
|
int currentValue;
|
||||||
|
do {
|
||||||
|
currentValue = index.get();
|
||||||
|
} while (!index.compareAndSet(currentValue, target));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,4 +100,7 @@ public interface StateMachine<S> extends BidirectionalStateManager<S>, AutoClose
|
|||||||
* @return 切换成功返回真, 否则返回假
|
* @return 切换成功返回真, 否则返回假
|
||||||
*/
|
*/
|
||||||
boolean switchTo(S state);
|
boolean switchTo(S state);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void close() throws Exception {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -253,6 +253,9 @@ public final class StateMachineBuilder<S> {
|
|||||||
if (type.equals(StateMachineType.STANDARD)) {
|
if (type.equals(StateMachineType.STANDARD)) {
|
||||||
return (M)new StandardStateMachine<>(stateList, entryHandlers,
|
return (M)new StandardStateMachine<>(stateList, entryHandlers,
|
||||||
leaveHandlers, exchangeHandlers, eventRegistries, executor, async);
|
leaveHandlers, exchangeHandlers, eventRegistries, executor, async);
|
||||||
|
} else if (type.equals(StateMachineType.CONCURRENT)) {
|
||||||
|
return (M)new DefaultConcurrentStateMachine<>(stateList, entryHandlers,
|
||||||
|
leaveHandlers, exchangeHandlers, eventRegistries, executor, async);
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("未知的状态机类型: " + type);
|
throw new IllegalArgumentException("未知的状态机类型: " + type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return stateList.size();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSwitchable() {
|
public boolean isSwitchable() {
|
||||||
return stateList.size() > 1;
|
return stateList.size() > 1;
|
||||||
@@ -140,6 +145,16 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
|
|||||||
return stateList.get(index);
|
return stateList.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定下标的状态
|
||||||
|
*
|
||||||
|
* @param index 下标
|
||||||
|
* @return 状态
|
||||||
|
*/
|
||||||
|
protected S get(int index) {
|
||||||
|
return stateList.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定状态在状态列表中的序号
|
* 获取指定状态在状态列表中的序号
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ public interface StateManager<S> {
|
|||||||
*/
|
*/
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前状态数量
|
||||||
|
* @return 数量
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否可切换
|
* 是否可切换
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.serliunx.statemanagement;
|
package com.serliunx.statemanagement;
|
||||||
|
|
||||||
|
import com.serliunx.statemanagement.machine.ConcurrentStateMachine;
|
||||||
import com.serliunx.statemanagement.machine.StateMachine;
|
import com.serliunx.statemanagement.machine.StateMachine;
|
||||||
import com.serliunx.statemanagement.machine.StateMachineBuilder;
|
import com.serliunx.statemanagement.machine.StateMachineBuilder;
|
||||||
import com.serliunx.statemanagement.support.PrinterEvent;
|
import com.serliunx.statemanagement.support.PrinterEvent;
|
||||||
|
|||||||
Reference in New Issue
Block a user