Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
Vyacheslav Boyko | 43b98e80c0 | |
Vyacheslav Boyko | d13761c6a8 | |
Vyacheslav Boyko | ac4537e3e1 | |
Vyacheslav Boyko | 1b2e812ca6 | |
Vyacheslav Boyko | efa3f8616b | |
Vyacheslav Boyko | b2d39772fc | |
Vyacheslav Boyko | fe5d5a2502 | |
Vyacheslav Boyko | 9db96a2b37 | |
Vyacheslav Boyko | 4712c1b423 | |
Vyacheslav Boyko | 92a75db1b4 | |
Vyacheslav Boyko | 1297474ef5 | |
Vyacheslav Boyko | dd88e919d1 | |
Vyacheslav Boyko | 99babc5b5a | |
Vyacheslav Boyko | 8ab3306142 | |
Vyacheslav Boyko | 151ed07472 | |
Vyacheslav Boyko | 7dd25dbfb5 | |
Vyacheslav Boyko | 2f84ae09d8 | |
Vyacheslav Boyko | e8c42bd2c4 | |
Vyacheslav Boyko | bb085efa88 | |
Vyacheslav Boyko | 192fb69677 | |
Vyacheslav Boyko | 9fb2276ac1 | |
Vyacheslav Boyko | 35285b61bf | |
Vyacheslav Boyko | ee4e214f8e | |
Vyacheslav Boyko | 87c5e92200 |
2
pom.xml
2
pom.xml
|
@ -7,7 +7,7 @@
|
|||
|
||||
<groupId>me.bvn13.fsm</groupId>
|
||||
<artifactId>fsm</artifactId>
|
||||
<version>2.1.6</version>
|
||||
<version>2.2.1</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
|
25
readme.md
25
readme.md
|
@ -50,6 +50,31 @@ Simple way to use it - to construct an inherited class specified with the type o
|
|||
.create();
|
||||
```
|
||||
|
||||
or since 2.2.1
|
||||
|
||||
```java
|
||||
SimpleFsm<String> simpleFsm = Fsm
|
||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
||||
.withStates()
|
||||
.from("init")
|
||||
.withBeforeHandler(fsm -> initBefore.set(true))
|
||||
.withAfterHandler(fsm -> initAfter.set(true))
|
||||
.withProcessor((fsm, event) -> initProcess.set(true))
|
||||
.withTransition()
|
||||
.to("finish")
|
||||
.checking((fsm, event) -> true)
|
||||
.endTransition()
|
||||
.end()
|
||||
.finish("finish")
|
||||
.withBeforeHandler(fsm -> finishBefore.set(true))
|
||||
.withAfterHandler(fsm -> finishAfter.set(true))
|
||||
.withProcessor((fsm, event) -> finishProcess.set(true))
|
||||
.end()
|
||||
.create();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Releasing
|
||||
|
||||
Creating a new release involves the following steps:
|
||||
|
|
|
@ -3,12 +3,20 @@ package me.bvn13.fsm;
|
|||
public class ConditionBuilder<T extends Fsm, E> {
|
||||
|
||||
private final FsmBuilder<T,E> fsmBuilder;
|
||||
private final StateBuilder<T, E> stateBuilder;
|
||||
private String from;
|
||||
private String to;
|
||||
private Condition<T,E> condition;
|
||||
|
||||
ConditionBuilder(FsmBuilder<T,E> fsmBuilder) {
|
||||
this.fsmBuilder = fsmBuilder;
|
||||
this.stateBuilder = null;
|
||||
}
|
||||
|
||||
ConditionBuilder(FsmBuilder<T,E> fsmBuilder, StateBuilder<T, E> stateBuilder, String from) {
|
||||
this.fsmBuilder = fsmBuilder;
|
||||
this.stateBuilder = stateBuilder;
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public ConditionBuilder<T,E> from(String from) {
|
||||
|
@ -31,4 +39,12 @@ public class ConditionBuilder<T extends Fsm, E> {
|
|||
return fsmBuilder;
|
||||
}
|
||||
|
||||
public StateBuilder<T, E> endTransition() {
|
||||
if (stateBuilder == null) {
|
||||
throw new IllegalStateException("Use '.end()' instead");
|
||||
}
|
||||
end();
|
||||
return stateBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* <b>Final State Machine</b>
|
||||
|
@ -50,6 +52,8 @@ import java.util.function.Supplier;
|
|||
* Simple way to use it - to construct an inherited class specified with the type of events to be processed
|
||||
* during transitions.
|
||||
*
|
||||
* since 2.1.5
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* SimpleFsm<String> simpleFsm = Fsm
|
||||
|
@ -74,6 +78,31 @@ import java.util.function.Supplier;
|
|||
* }
|
||||
* </pre>
|
||||
*
|
||||
* or since 2.2.1
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* SimpleFsm<String> simpleFsm = Fsm
|
||||
* .<SimpleFsm<String>, String>from(SimpleFsm::new)
|
||||
* .withStates()
|
||||
* .from("init")
|
||||
* .withBeforeHandler(fsm -> initBefore.set(true))
|
||||
* .withAfterHandler(fsm -> initAfter.set(true))
|
||||
* .withProcessor((fsm, event) -> initProcess.set(true))
|
||||
* .withTransition()
|
||||
* .to("finish")
|
||||
* .checking((fsm, event) -> true)
|
||||
* .endTransition()
|
||||
* .end()
|
||||
* .finish("finish")
|
||||
* .withBeforeHandler(fsm -> finishBefore.set(true))
|
||||
* .withAfterHandler(fsm -> finishAfter.set(true))
|
||||
* .withProcessor((fsm, event) -> finishProcess.set(true))
|
||||
* .end()
|
||||
* .create();
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Otherwise you are able to use Old syntax:
|
||||
*
|
||||
|
@ -147,9 +176,9 @@ public class Fsm<T extends Fsm, E> {
|
|||
return;
|
||||
}
|
||||
currentState.process(event);
|
||||
currentState.afterEvent();
|
||||
if (currentState.isFinish()) {
|
||||
done = true;
|
||||
currentState.afterEvent();
|
||||
return;
|
||||
}
|
||||
switchToNextState(event);
|
||||
|
@ -239,6 +268,19 @@ public class Fsm<T extends Fsm, E> {
|
|||
addTransition(fromState, toState.getName(), condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a possibility to initialize FSM in custom State
|
||||
* @param name State name (must be added before)
|
||||
*/
|
||||
protected void setCurrentState(String name) {
|
||||
try {
|
||||
this.currentState = this.states.get(name);
|
||||
} catch (NullPointerException e) {
|
||||
throw new NotInitializedException(format("Unable to find state '%s'", name), e);
|
||||
}
|
||||
this.done = currentState.isFinish();
|
||||
}
|
||||
|
||||
private void switchToNextState(E event) {
|
||||
if (!transitions.containsKey(currentState.getName())) {
|
||||
throw new TransitionMissedException(currentState.getName());
|
||||
|
@ -263,9 +305,10 @@ public class Fsm<T extends Fsm, E> {
|
|||
}
|
||||
|
||||
private void nextState(State<E> state, E event) {
|
||||
state.beforeEvent();
|
||||
currentState.afterEvent();
|
||||
previousState = currentState;
|
||||
currentState = state;
|
||||
currentState.beforeEvent();
|
||||
}
|
||||
|
||||
private void checkStateExist(String name) throws StateAlreadyExistsException {
|
||||
|
|
|
@ -31,6 +31,11 @@ public class FsmBuilder<T extends Fsm, E> {
|
|||
return fsm;
|
||||
}
|
||||
|
||||
public T startingAt(String name) {
|
||||
fsm.setCurrentState(name);
|
||||
return fsm;
|
||||
}
|
||||
|
||||
T getFsm() {
|
||||
return fsm;
|
||||
}
|
||||
|
|
|
@ -56,4 +56,8 @@ public class StateBuilder<T extends Fsm, E> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ConditionBuilder<T,E> withTransition() {
|
||||
return new ConditionBuilder<>(fsmBuilder, this, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,6 @@ package me.bvn13.fsm;
|
|||
@FunctionalInterface
|
||||
public interface StateHandler<T extends Fsm> {
|
||||
|
||||
void handle(T fms);
|
||||
void handle(T fsm);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@ package me.bvn13.fsm;
|
|||
@FunctionalInterface
|
||||
public interface StateProcessor<T extends Fsm, E> {
|
||||
|
||||
void process(T fms, E event);
|
||||
void process(T fsm, E event);
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import me.bvn13.fsm.StateHandler;
|
|||
|
||||
public class DummyHandler<T extends Fsm> implements StateHandler<T> {
|
||||
@Override
|
||||
public void handle(T fms) {
|
||||
public void handle(T fsm) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import me.bvn13.fsm.StateProcessor;
|
|||
|
||||
public class DummyProcessor<T extends Fsm,E> implements StateProcessor<T,E> {
|
||||
@Override
|
||||
public void process(T fms, E event) {
|
||||
public void process(T fsm, E event) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package me.bvn13.fsm.exceptions;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* is thrown if there are more than 1 appropriate transition from current state
|
||||
*/
|
||||
|
@ -10,11 +12,14 @@ public class AmbiguousTransitionException extends FsmException {
|
|||
super(message);
|
||||
}
|
||||
public AmbiguousTransitionException(String from, List<String> next) {
|
||||
super("");
|
||||
String msg = "";
|
||||
for (String to : next) {
|
||||
msg += (msg.length() > 0 ? ", " : "") + to;
|
||||
super(format("Ambiguous transition from state %s. Candidates are: %s", from, join(next)));
|
||||
}
|
||||
|
||||
private static String join(List<String> list) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
for (String to : list) {
|
||||
msg.append(msg.length() > 0 ? ", " : "").append(to);
|
||||
}
|
||||
this.message = String.format("Ambiguous transition from state %s. Candidates are: %s", from, msg);
|
||||
return msg.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,14 @@
|
|||
package me.bvn13.fsm.exceptions;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Parent FSM exception class
|
||||
*/
|
||||
public class FsmException extends RuntimeException {
|
||||
protected String message;
|
||||
public FsmException(String message) {
|
||||
this.message = message;
|
||||
super(message);
|
||||
}
|
||||
protected String getStackTraceString() {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
this.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
public void printStackTrace() {
|
||||
System.out.println(String.format("FSMException: %s / %s", message, getStackTraceString()));
|
||||
|
||||
public FsmException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,12 @@ public class NotInitializedException extends FsmException {
|
|||
public NotInitializedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotInitializedException(String message, Exception e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
public NotInitializedException() {
|
||||
super("FSM is not inited");
|
||||
super("FSM is not initialized");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.junit.Assert;
|
|||
import org.junit.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by bvn13 on 28.12.2017.
|
||||
|
@ -92,6 +93,8 @@ public class FsmTest {
|
|||
.withAfterHandler(fsm -> initAfter.set(true))
|
||||
.withProcessor((fsm, event) -> initProcess.set(true))
|
||||
.end()
|
||||
.state("intermediate")
|
||||
.end()
|
||||
.finish("finish")
|
||||
.withBeforeHandler(fsm -> finishBefore.set(true))
|
||||
.withAfterHandler(fsm -> finishAfter.set(true))
|
||||
|
@ -99,17 +102,21 @@ public class FsmTest {
|
|||
.end()
|
||||
.withTransition()
|
||||
.from("init")
|
||||
.to("intermediate")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.withTransition()
|
||||
.from("intermediate")
|
||||
.to("finish")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.create()
|
||||
;
|
||||
.create();
|
||||
|
||||
// @formatter:on
|
||||
|
||||
simpleFsm.process("");
|
||||
simpleFsm.process("");
|
||||
|
||||
//Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
||||
Assert.assertTrue(initBefore.get());
|
||||
Assert.assertTrue(initProcess.get());
|
||||
Assert.assertTrue(initAfter.get());
|
||||
|
@ -119,4 +126,218 @@ public class FsmTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newSyntaxCustomState() {
|
||||
|
||||
AtomicBoolean initBefore = new AtomicBoolean(false);
|
||||
AtomicBoolean initAfter = new AtomicBoolean(false);
|
||||
AtomicBoolean initProcess = new AtomicBoolean(false);
|
||||
AtomicBoolean intermediateBefore = new AtomicBoolean(false);
|
||||
AtomicBoolean intermediateAfter = new AtomicBoolean(false);
|
||||
AtomicBoolean intermediateProcess = new AtomicBoolean(false);
|
||||
AtomicBoolean finishBefore = new AtomicBoolean(false);
|
||||
AtomicBoolean finishAfter = new AtomicBoolean(false);
|
||||
AtomicBoolean finishProcess = new AtomicBoolean(false);
|
||||
|
||||
// @formatter:off
|
||||
|
||||
SimpleFsm<String> simpleFsm = Fsm
|
||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
||||
.withStates()
|
||||
.from("init")
|
||||
.withBeforeHandler(fsm -> initBefore.set(true))
|
||||
.withAfterHandler(fsm -> initAfter.set(true))
|
||||
.withProcessor((fsm, event) -> initProcess.set(true))
|
||||
.end()
|
||||
.state("intermediate")
|
||||
.withBeforeHandler(fsm -> intermediateBefore.set(true))
|
||||
.withAfterHandler(fsm -> intermediateAfter.set(true))
|
||||
.withProcessor((fsm, event) -> intermediateProcess.set(true))
|
||||
.end()
|
||||
.finish("finish")
|
||||
.withBeforeHandler(fsm -> finishBefore.set(true))
|
||||
.withAfterHandler(fsm -> finishAfter.set(true))
|
||||
.withProcessor((fsm, event) -> finishProcess.set(true))
|
||||
.end()
|
||||
.withTransition()
|
||||
.from("init")
|
||||
.to("intermediate")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.withTransition()
|
||||
.from("intermediate")
|
||||
.to("finish")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.startingAt("intermediate")
|
||||
;
|
||||
|
||||
// @formatter:on
|
||||
|
||||
simpleFsm.process("");
|
||||
|
||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
||||
Assert.assertFalse(initBefore.get());
|
||||
Assert.assertFalse(initProcess.get());
|
||||
Assert.assertFalse(initAfter.get());
|
||||
Assert.assertFalse(intermediateBefore.get());
|
||||
Assert.assertTrue(intermediateAfter.get());
|
||||
Assert.assertTrue(intermediateProcess.get());
|
||||
Assert.assertTrue(finishBefore.get());
|
||||
Assert.assertFalse(finishProcess.get());
|
||||
Assert.assertFalse(finishAfter.get());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newSyntaxCountingEveryStep() {
|
||||
|
||||
Counter initCounter = new Counter();
|
||||
Counter firstIntermediateCounter = new Counter();
|
||||
Counter secondIntermediateCounter = new Counter();
|
||||
Counter finishCounter = new Counter();
|
||||
|
||||
// @formatter:off
|
||||
|
||||
SimpleFsm<String> simpleFsm = Fsm
|
||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
||||
.withStates()
|
||||
.from("init")
|
||||
.withBeforeHandler(fsm -> initCounter.before.incrementAndGet())
|
||||
.withAfterHandler(fsm -> initCounter.after.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> initCounter.process.incrementAndGet())
|
||||
.end()
|
||||
.state("intermediate-1")
|
||||
.withBeforeHandler(fsm -> firstIntermediateCounter.before.incrementAndGet())
|
||||
.withAfterHandler(fsm -> firstIntermediateCounter.after.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> firstIntermediateCounter.process.incrementAndGet())
|
||||
.end()
|
||||
.state("intermediate-2")
|
||||
.withBeforeHandler(fsm -> secondIntermediateCounter.before.incrementAndGet())
|
||||
.withAfterHandler(fsm -> secondIntermediateCounter.after.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> secondIntermediateCounter.process.incrementAndGet())
|
||||
.end()
|
||||
.finish("finish")
|
||||
.withBeforeHandler(fsm -> finishCounter.before.incrementAndGet())
|
||||
.withAfterHandler(fsm -> finishCounter.after.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> finishCounter.process.incrementAndGet())
|
||||
.end()
|
||||
.withTransition()
|
||||
.from("init")
|
||||
.to("intermediate-1")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.withTransition()
|
||||
.from("intermediate-1")
|
||||
.to("intermediate-2")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.withTransition()
|
||||
.from("intermediate-2")
|
||||
.to("finish")
|
||||
.checking((fsm, event) -> true)
|
||||
.end()
|
||||
.create()
|
||||
;
|
||||
|
||||
// @formatter:on
|
||||
|
||||
simpleFsm.process("");
|
||||
simpleFsm.process("");
|
||||
simpleFsm.process("");
|
||||
|
||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
||||
Assert.assertEquals(1, initCounter.before.get());
|
||||
Assert.assertEquals(1, initCounter.after.get());
|
||||
Assert.assertEquals(1, initCounter.process.get());
|
||||
Assert.assertEquals(1, firstIntermediateCounter.before.get());
|
||||
Assert.assertEquals(1, firstIntermediateCounter.after.get());
|
||||
Assert.assertEquals(1, firstIntermediateCounter.process.get());
|
||||
Assert.assertEquals(1, secondIntermediateCounter.before.get());
|
||||
Assert.assertEquals(1, secondIntermediateCounter.after.get());
|
||||
Assert.assertEquals(1, secondIntermediateCounter.process.get());
|
||||
Assert.assertEquals(1, finishCounter.before.get());
|
||||
Assert.assertEquals(0, finishCounter.after.get());
|
||||
Assert.assertEquals(0, finishCounter.process.get());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newSyntaxOfTransitions() {
|
||||
|
||||
Counter initCounter = new Counter();
|
||||
Counter firstIntermediateCounter = new Counter();
|
||||
Counter secondIntermediateCounter = new Counter();
|
||||
Counter finishCounter = new Counter();
|
||||
|
||||
// @formatter:off
|
||||
|
||||
SimpleFsm<String> simpleFsm = Fsm
|
||||
.<SimpleFsm<String>, String>from(SimpleFsm::new)
|
||||
.withStates()
|
||||
.from("init")
|
||||
.withBeforeHandler(fsm -> initCounter.before.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> initCounter.process.incrementAndGet())
|
||||
.withAfterHandler(fsm -> initCounter.after.incrementAndGet())
|
||||
.withTransition()
|
||||
.to("intermediate-1")
|
||||
.checking((fsm, event) -> true)
|
||||
.endTransition()
|
||||
.end()
|
||||
.state("intermediate-1")
|
||||
.withBeforeHandler(fsm -> firstIntermediateCounter.before.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> firstIntermediateCounter.process.incrementAndGet())
|
||||
.withAfterHandler(fsm -> firstIntermediateCounter.after.incrementAndGet())
|
||||
.withTransition()
|
||||
.from("intermediate-1")
|
||||
.to("intermediate-2")
|
||||
.checking((fsm, event) -> true)
|
||||
.endTransition()
|
||||
.end()
|
||||
.state("intermediate-2")
|
||||
.withBeforeHandler(fsm -> secondIntermediateCounter.before.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> secondIntermediateCounter.process.incrementAndGet())
|
||||
.withAfterHandler(fsm -> secondIntermediateCounter.after.incrementAndGet())
|
||||
.end()
|
||||
.finish("finish")
|
||||
.withBeforeHandler(fsm -> finishCounter.before.incrementAndGet())
|
||||
.withProcessor((fsm, event) -> finishCounter.process.incrementAndGet())
|
||||
.withAfterHandler(fsm -> finishCounter.after.incrementAndGet())
|
||||
.withTransition()
|
||||
.from("intermediate-2")
|
||||
.to("finish")
|
||||
.checking((fsm, event) -> true)
|
||||
.endTransition()
|
||||
.end()
|
||||
.create()
|
||||
;
|
||||
|
||||
// @formatter:on
|
||||
|
||||
simpleFsm.process("");
|
||||
simpleFsm.process("");
|
||||
simpleFsm.process("");
|
||||
|
||||
Assert.assertEquals("finish", simpleFsm.getCurrentState().getName());
|
||||
Assert.assertEquals(1, initCounter.before.get());
|
||||
Assert.assertEquals(1, initCounter.after.get());
|
||||
Assert.assertEquals(1, initCounter.process.get());
|
||||
Assert.assertEquals(1, firstIntermediateCounter.before.get());
|
||||
Assert.assertEquals(1, firstIntermediateCounter.after.get());
|
||||
Assert.assertEquals(1, firstIntermediateCounter.process.get());
|
||||
Assert.assertEquals(1, secondIntermediateCounter.before.get());
|
||||
Assert.assertEquals(1, secondIntermediateCounter.after.get());
|
||||
Assert.assertEquals(1, secondIntermediateCounter.process.get());
|
||||
Assert.assertEquals(1, finishCounter.before.get());
|
||||
Assert.assertEquals(0, finishCounter.after.get());
|
||||
Assert.assertEquals(0, finishCounter.process.get());
|
||||
|
||||
}
|
||||
|
||||
static class Counter {
|
||||
final AtomicInteger before = new AtomicInteger(0);
|
||||
final AtomicInteger after = new AtomicInteger(0);
|
||||
final AtomicInteger process = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue