doc: 文档标准化.

This commit is contained in:
2025-05-16 17:16:50 +08:00
parent c0ccf2cb4f
commit f733e1ff5a
14 changed files with 146 additions and 50 deletions

View File

@@ -1,8 +1,9 @@
package com.serliunx.statemanagement.machine;
/**
* 基本行为与{@link StateMachine} 一致, 最大不同是切换状态不再使用直接的锁机制, 具体由实现类决定
* <li> 默认实现{@link DefaultConcurrentStateMachine}, 状态切换序列由CAS实现.
* 基本行为与{@link StateMachine} 一致, 最大不同是切换状态不再使用直接的锁机制, 具体由实现类决定;
* <p>
* 默认实现{@link DefaultConcurrentStateMachine}, 状态切换序列由CAS实现.
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @version 1.0.0
@@ -12,8 +13,7 @@ package com.serliunx.statemanagement.machine;
public interface ConcurrentStateMachine<S> extends StateMachine<S> {
/**
* 尝试使用CAS更新状态
* <li> 成功更新时触发状态处理器
* 尝试使用CAS更新状态, 成功更新时触发状态处理器
*
* @param expectedValue 前置状态
* @param newValue 更新的状态值

View File

@@ -161,6 +161,8 @@ public class DefaultConcurrentStateMachine<S> extends AbstractStateMachine<S> im
/**
* 是否为默认状态
*
* @return 默认状态时返回真, 否则返回假.
*/
protected boolean isDefault() {
return index.get() == 0;
@@ -168,7 +170,9 @@ public class DefaultConcurrentStateMachine<S> extends AbstractStateMachine<S> im
/**
* 移动下标至上一个状态
* <li> 使用CAS一直尝试, 直到成功
* <p>
* 使用CAS一直尝试, 直到成功
* </p>
*/
protected void exchangeToPrev() {
final int size = size();
@@ -180,7 +184,9 @@ public class DefaultConcurrentStateMachine<S> extends AbstractStateMachine<S> im
/**
* 移动下标至下一个状态
* <li> 使用CAS一直尝试, 直到成功
* <p>
* 使用CAS一直尝试, 直到成功
* </p>
*/
protected void exchangeToNext() {
final int size = size();
@@ -192,7 +198,9 @@ public class DefaultConcurrentStateMachine<S> extends AbstractStateMachine<S> im
/**
* 切换到指定状态值
* <li> 使用CAS一直尝试, 直到成功
* <p>
* 使用CAS一直尝试, 直到成功
* </p>
*
* @param target 目标值
*/

View File

@@ -18,8 +18,10 @@ public final class HandlerInvocationDelegate {
/**
* 触发处理器
*
* @param context 状态机上下文
* @param from 源状态
* @param to 目的状态
* @param <S> 状态类型
*/
public static <S> void invokeHandlers(StateMachineContext<S> context, S from, S to) {
// 触发离开处理器
@@ -35,6 +37,12 @@ public final class HandlerInvocationDelegate {
/**
* 触发逻辑
*
* @param context 状态机上下文
* @param handlerWrappers 封装后处理器集合
* @param from 源状态
* @param to 目的状态
* @param <S> 状态类型
*/
public static <S> void doInvokeHandlers(StateMachineContext<S> context,
List<StateHandlerWrapper<S>> handlerWrappers, S from, S to) {

View File

@@ -7,8 +7,10 @@ import java.util.concurrent.Executor;
/**
* 状态机之状态事件注册
* <li> 注册状态切换时的事件, 一般用于状态机构建和支持动态调整的状态机{@link FlexibleStateMachine};
* <p>
* 注册状态切换时的事件, 一般用于状态机构建和支持动态调整的状态机{@link FlexibleStateMachine};
* 当然实际不仅于此, 任何相关的都可以使用.
* </p>
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 2025/3/28
@@ -18,94 +20,121 @@ public interface StateEventRegistry<S> {
/**
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
* <p>
* 切换到了指定状态时执行的逻辑
* </p>
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> whenEntry(S state, StateHandler<S> handler, Boolean async, Executor executor);
/**
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
* <p>
* 切换到了指定状态时执行的逻辑
* </p>
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> whenEntry(S state, StateHandler<S> handler, Boolean async);
/**
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
* <p>
* 切换到了指定状态时执行的逻辑
* </p>
*
* @param state 状态
* @param handler 处理逻辑
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> whenEntry(S state, StateHandler<S> handler);
/**
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
* <p>
* 从指定状态切换到别的状态时执行的逻辑
* </p>
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> whenLeave(S state, StateHandler<S> handler, Boolean async, Executor executor);
/**
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
* <p>
* 从指定状态切换到别的状态时执行的逻辑
* </p>
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> whenLeave(S state, StateHandler<S> handler, Boolean async);
/**
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
* <p>
* 从指定状态切换到别的状态时执行的逻辑
* </p>
*
* @param state 状态
* @param handler 处理逻辑
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> whenLeave(S state, StateHandler<S> handler);
/**
* 添加交换事件
* <li> 从A状态切换至B状态时触发
* <p>
* 从A状态切换至B状态时触发
* </p>
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> exchange(S from, S to, StateHandler<S> handler, Boolean async, Executor executor);
/**
* 添加交换事件
* <li> 从A状态切换至B状态时触发
* <p>
* 从A状态切换至B状态时触发
* </p>
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @param async 是否异步执行
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> exchange(S from, S to, StateHandler<S> handler, Boolean async);
/**
* 添加交换事件
* <li> 从A状态切换至B状态时触发
* <p>
* 从A状态切换至B状态时触发
* </p>
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @return 当前对象, 链式调用
*/
StateEventRegistry<S> exchange(S from, S to, StateHandler<S> handler);
}

View File

@@ -7,9 +7,11 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager;
* <p>
* 基于双向的状态管理器扩展 {@link BidirectionalStateManager};
* 同时可以监听多种事件和发布事件, 包括:
* <ul>
* <li> 切换至指定状态时触发 (进入事件)
* <li> 切出指定状态时触发 (离开事件)
* <li> 从A切换到B状态时触发 (交换事件)
* </ul>
* <p>
* 请使用 {@link StateMachineBuilder} 来构建状态机.
*
@@ -77,7 +79,9 @@ public interface StateMachine<S> extends BidirectionalStateManager<S>, AutoClose
/**
* 切换至指定状态
* <li> 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
* <p>
* 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
* </p>
*
* @param invokeHandlers 是否唤醒状态处理器
* @param state 新的状态
@@ -94,7 +98,9 @@ public interface StateMachine<S> extends BidirectionalStateManager<S>, AutoClose
/**
* 切换至指定状态
* <li> 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
* <p>
* 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
* </p>
*
* @param state 新的状态
* @return 切换成功返回真, 否则返回假

View File

@@ -57,6 +57,7 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
* 定义初始状态
*
* @param initialState 初始状态
* @return 状态机构建
*/
public StateMachineBuilder<S> withInitial(S initialState) {
this.initialState = initialState;
@@ -123,6 +124,7 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
*
* @param event 事件
* @param logic 切换逻辑
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> whenHappened(Object event, Consumer<StateMachine<S>> logic) {
List<Consumer<StateMachine<S>>> consumers = eventRegistries.computeIfAbsent(event, k -> new ArrayList<>());
@@ -136,6 +138,7 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
* 优先级低于添加事件时指定的执行器
*
* @param executor 执行器
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> executor(Executor executor) {
this.executor = executor;
@@ -146,6 +149,7 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
* 定义状态机是否异步执行
*
* @param async 是否异步执行
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> async(Boolean async) {
this.async = async;
@@ -154,6 +158,8 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/**
* 定义状态机为异步执行
*
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> async() {
return async(true);
@@ -161,9 +167,12 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/**
* 指定状态机的类型
* <li> 状态机并发与否并不影响事件的执行逻辑
* <p>
* 状态机并发与否并不影响事件的执行逻辑
* </p>
*
* @param type 类型
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> type(StateMachineType type) {
if (type == null) {
@@ -175,7 +184,11 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/**
* 指定状态机的类型为标准型
* <li> 状态机并发与否并不影响事件的执行逻辑
* <p>
* 状态机并发与否并不影响事件的执行逻辑
* </p>
*
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> standard() {
return type(StateMachineType.STANDARD);
@@ -183,14 +196,21 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/**
* 指定状态机的类型为并发型
* <li> 状态机并发与否并不影响事件的执行逻辑
* <p>
* 状态机并发与否并不影响事件的执行逻辑
* </p>
*
* @return 当前对象, 链式调用
*/
public StateMachineBuilder<S> concurrent() {
return type(StateMachineType.CONCURRENT);
}
/**
* 构建
* 执行构建
*
* @param <M> 状态机类型
* @return 状态机
*/
@SuppressWarnings("unchecked")
public <M extends StateMachine<S>> M build() {
@@ -210,6 +230,7 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/**
* 状态机构建器
*
* @param <S> 状态类型
* @param states 状态集合
* @return 状态机构建器实例
*/
@@ -220,6 +241,7 @@ public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/**
* 状态机构建器
*
* @param <S> 状态类型
* @param states 状态集合
* @return 状态机构建器实例
*/

View File

@@ -19,7 +19,8 @@ public final class StateHandlerWrapper<S> {
private final StateHandler<S> stateHandler;
/**
* 执行器
* <li> 用于异步执行处理逻辑
* <p>
* 用于异步执行处理逻辑
*/
private final Executor executor;
/**

View File

@@ -112,8 +112,10 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
/**
* 将序号移动至下一个
* <ul>
* <li> 自动归零
* <li> 仅在持有写锁的情况下访问
* </ul>
*/
@SuppressWarnings("all")
protected void next() {
@@ -123,8 +125,10 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
/**
* 将序号移动至上一个
* <ul>
* <li> 自动归零
* <li> 仅在持有写锁的情况下访问
* </ul>
*/
@SuppressWarnings("all")
protected void prev() {
@@ -137,7 +141,9 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
* <p>
* 类及子类访问当前状态时不允许使用{@link #current()},因为会造成死锁
*
* <li> 仅在持有锁的情况下访问
* <p>
* 仅在持有锁的情况下访问
* </p>
*
* @return 当前状态
*/
@@ -197,6 +203,8 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
/**
* 更新当前状态的序号
*
* @param newIndex 新的序号
*/
protected void updateCurrentIndex(int newIndex) {
index = newIndex;
@@ -204,6 +212,8 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
/**
* 状态序号默认值(等同于默认状态)
*
* @return 默认的状态值
*/
protected int getDefault() {
return defaultIndex;

View File

@@ -6,8 +6,10 @@ import java.util.List;
/**
* 断路的单向状态管理器
* <p> 逻辑与{@link UnidirectionalStateManager}大体相同, 不同的点在于:
* <li> 最后一个状态无法转向第一个状态, 即为一次性的状态管理器.
* <p>
* 逻辑与{@link UnidirectionalStateManager}大体相同, 不同的点在于:
* 最后一个状态无法转向第一个状态, 即为一次性的状态管理器.
* </p>
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @version 1.0.0

View File

@@ -2,7 +2,9 @@ package com.serliunx.statemanagement.manager;
/**
* 将指定状态管理器标记为循环的状态管理器
* <li> 允许单向、双向循环
* <p>
* 允许单向、双向循环
* </p>
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @version 1.0.0

View File

@@ -83,6 +83,9 @@ public class DefaultUnidirectionalStateManager<S> extends AbstractStateManager<S
/**
* 保留默认的切换方式供子类使用
*
* @param state 目标状态值
* @return 成功切换返回真, 否则返回假
*/
protected boolean defaultSwitchTo(S state) {
return super.switchTo(state);

View File

@@ -64,8 +64,10 @@ public interface StateManager<S> {
/**
* 如果是指定的状态则切换到另一个状态
* <li> 例: 检测当前状态是否为 1 且可切换, 如何为 1 则将状态切换到 2
* <li> 结合了 {@link #current()}、 {@link #switchTo(Object)} 及 {@link #isSwitchable()}
* <p>
* 例: 检测当前状态是否为 1 且可切换, 如何为 1 则将状态切换到 2;
* 结合了 {@link #current()}、 {@link #switchTo(Object)} 及 {@link #isSwitchable()}
* </p>
*
* @param now 当前状态
* @param newState 新的状态

View File

@@ -4,13 +4,13 @@ package com.serliunx.statemanagement.manager;
* 单向流转的状态管理器
* <p>
* 其基本逻辑等同于 {@link StateManager}, 但存在以下不同:
* <li> 状态只能单方向流动(最后一个状态允许切换至第一个状态), 如果有A, B, C, D 四种状态则存在以下几种情况:
* <p>
* <p>
* <li> A -> B 允许直接切换, A -> C 允许直接切换, C -> D 允许直接切换 等等..
* <li> B -> A 不允许切换, C -> A 不允许切换, D -> C 不允许切换 等等..
* <li> 特例: D -> A 是允许的, 因为D是最后一个状态, 故可以切换至第一个状态.
* <p>
* 状态只能单方向流动(最后一个状态允许切换至第一个状态), 如果有A, B, C, D 四种状态则存在以下几种情况:
* </p>
* <ul>
* <li> A B 允许直接切换, A C 允许直接切换, C D 允许直接切换 等等..
* <li> B A 不允许切换, C A 不允许切换, D C 不允许切换 等等..
* <li> 特例: D A 是允许的, 因为 D 是最后一个状态, 故可以切换至第一个状态.
* </ul>
* 即状态的切换只允许一个方向,不允许向前流动,除非到达最后一个状态!
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>

View File

@@ -15,8 +15,11 @@ public final class ExecutorUtils {
/**
* 快速获取自适应参数的线程池
* <li> 核心线程数量为当前处理器数量的两倍; 最大线程数量为当前处理器数量的四倍.
* <p>
* 核心线程数量为当前处理器数量的两倍; 最大线程数量为当前处理器数量的四倍.
* </p>
*
* @param rejectedExecutionHandler 拒绝策略
* @return 执行器(线程池)
*/
public static Executor adaptiveThreadPool(RejectedExecutionHandler rejectedExecutionHandler) {