change: 代码整理、定向切换时校验当前状态.
This commit is contained in:
@@ -149,8 +149,16 @@ public class StandardStateMachine<S> extends AbstractStateManager<S> implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean switchTo(S state) {
|
public boolean switchTo(S state) {
|
||||||
|
int i = indexOf(state);
|
||||||
|
if (i == -1 || i == currentIndex()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
writeLock.lock();
|
writeLock.lock();
|
||||||
|
// 重新检查
|
||||||
|
if (i == currentIndex()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
S oldState = get();
|
S oldState = get();
|
||||||
boolean result = super.switchTo(state);
|
boolean result = super.switchTo(state);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
|||||||
* <li> 切出指定状态时触发 (离开事件)
|
* <li> 切出指定状态时触发 (离开事件)
|
||||||
* <li> 从A切换到B状态时触发 (交换事件)
|
* <li> 从A切换到B状态时触发 (交换事件)
|
||||||
* <p>
|
* <p>
|
||||||
* 推荐使用{@link StateMachineBuilder} 来构建状态机.
|
* 请使用{@link StateMachineBuilder} 来构建状态机.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
|
||||||
* @version 1.0.0
|
* @version 1.0.0
|
||||||
@@ -22,5 +22,12 @@ import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
|||||||
*/
|
*/
|
||||||
public interface StateMachine<S> extends BidirectionalStateManager<S> {
|
public interface StateMachine<S> extends BidirectionalStateManager<S> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换到指定状态
|
||||||
|
* <li> 在使用状态机的情况, 仅切换成功才会触发注册的各种事件.
|
||||||
|
*
|
||||||
|
* @param state 新的状态
|
||||||
|
* @return 切换成功返回真, 否则返回假
|
||||||
|
*/
|
||||||
|
boolean switchTo(S state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.serliunx.statemanagement.machine;
|
|||||||
|
|
||||||
import com.serliunx.statemanagement.machine.handler.StateHandler;
|
import com.serliunx.statemanagement.machine.handler.StateHandler;
|
||||||
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
|
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
|
||||||
import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.serliunx.statemanagement.machine.handler;
|
package com.serliunx.statemanagement.machine.handler;
|
||||||
|
|
||||||
import com.serliunx.statemanagement.manager.BidirectionalStateManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态处理器入参
|
* 状态处理器入参
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -74,11 +74,15 @@ public abstract class AbstractStateManager<S> implements StateManager<S> {
|
|||||||
@Override
|
@Override
|
||||||
public boolean switchTo(S state) {
|
public boolean switchTo(S state) {
|
||||||
int i = indexOf(state);
|
int i = indexOf(state);
|
||||||
if (i == -1) {
|
if (i == -1 || i == index) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
writeLock.lock();
|
writeLock.lock();
|
||||||
|
// 重新检查
|
||||||
|
if (i == index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
index = i;
|
index = i;
|
||||||
} finally {
|
} finally {
|
||||||
writeLock.unlock();
|
writeLock.unlock();
|
||||||
|
|||||||
@@ -61,11 +61,18 @@ public class DefaultUnidirectionalStateManager<S> extends AbstractStateManager<S
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean switchTo(S state) {
|
public boolean switchTo(S state) {
|
||||||
try {
|
|
||||||
writeLock.lock();
|
|
||||||
final int i;
|
final int i;
|
||||||
if ((i = indexOf(state)) == -1 ||
|
if ((i = indexOf(state)) == -1 ||
|
||||||
(!isLast() && i < currentIndex()) ||
|
i == currentIndex()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
writeLock.lock();
|
||||||
|
// 重新检查
|
||||||
|
if (i == currentIndex()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((!isLast() && i < currentIndex()) ||
|
||||||
(isLast() && i != getDefault())) {
|
(isLast() && i != getDefault())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.serliunx.statemanagement.manager;
|
package com.serliunx.statemanagement.manager;
|
||||||
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态管理器
|
* 状态管理器
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -22,20 +22,23 @@ public class MachineTest {
|
|||||||
public void testStandardStateMachine() {
|
public void testStandardStateMachine() {
|
||||||
StateMachine<PrinterState> stateMachine = StateMachineBuilder.from(PrinterState.class)
|
StateMachine<PrinterState> stateMachine = StateMachineBuilder.from(PrinterState.class)
|
||||||
.async(false)
|
.async(false)
|
||||||
|
.states(PrinterState.values())
|
||||||
|
.executor(Executors.newFixedThreadPool(16))
|
||||||
.whenLeave(PrinterState.PRINTING, h -> {
|
.whenLeave(PrinterState.PRINTING, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": leave PRINTING");
|
System.out.println(Thread.currentThread().getName() + ": leave PRINTING");
|
||||||
})
|
})
|
||||||
.states(PrinterState.values())
|
|
||||||
.executor(Executors.newFixedThreadPool(16))
|
|
||||||
.whenEntry(PrinterState.SCANNING, h -> {
|
.whenEntry(PrinterState.SCANNING, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
||||||
}, false)
|
})
|
||||||
.whenEntry(PrinterState.PRINTING, h -> {
|
.whenEntry(PrinterState.PRINTING, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
||||||
}, false, Executors.newFixedThreadPool(1))
|
})
|
||||||
.exchange(PrinterState.STOPPED, PrinterState.IDLE, h -> {
|
.exchange(PrinterState.STOPPED, PrinterState.IDLE, h -> {
|
||||||
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
System.out.println(Thread.currentThread().getName() + ": " + h.getFrom() + " >>> " + h.getTo());
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
stateMachine.switchTo(PrinterState.PRINTING);
|
||||||
|
stateMachine.switchNext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.serliunx.statemanagement;
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -15,6 +18,10 @@ public class ManagerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnidirectionalStateManager() {
|
public void testUnidirectionalStateManager() {
|
||||||
|
UnidirectionalStateManager<PrinterState> unidirectionalStateManager =
|
||||||
|
new DefaultUnidirectionalStateManager<>(PrinterState.values());
|
||||||
|
|
||||||
|
System.out.println(unidirectionalStateManager.switchTo(PrinterState.IDLE));
|
||||||
|
System.out.println(unidirectionalStateManager.switchTo(PrinterState.SCANNING));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user