Java 基于枚举的有限状态机中竞争条件的避免
我有一个基于枚举的状态机。下面是示例代码,用于说明我的状态结构和我遇到的问题Java 基于枚举的有限状态机中竞争条件的避免,java,android,state-machine,Java,Android,State Machine,我有一个基于枚举的状态机。下面是示例代码,用于说明我的状态结构和我遇到的问题 public enum LinkStates implements StuffDoneListener { ... DO_SOME_WORK { public void process() { .... .... someObject.startDoingSpecialStuff(); o
public enum LinkStates implements StuffDoneListener {
...
DO_SOME_WORK {
public void process() {
....
....
someObject.startDoingSpecialStuff();
outerClass.toState(WAIT_FOR_EVENT);
}
},
WAIT_FOR_EVENT {
public void process() {
// does nothing
}
public void onSpecialStuffComplete() {
}
}
...
// Default implementation of interface methods which individual states
// may override at will
public void onSpecialStuffComplete() {
}
}
process()
方法是状态更改时调用的方法。每个状态还倾向于覆盖各种侦听器方法以接收各种事件
StateDO\u SOME\u WORK
调用对象上的方法(startDoingSpecialStuff()
),使其执行一些长时间的工作。该对象在另一个非UI线程上执行其工作。完成后,状态机将通过调用工作的原始线程调用的onSpecialStuffComplete()
得到通知。这里明显的问题是,如果工作很快完成,可能会出现争用情况,即在侦听器回调触发后,FSM进入WAIT\u FOR\u事件
“修复”这个问题对我来说非常简单,也许还可以覆盖DO\u SOME\u WORK
中的onSpecialStuffComplete()
,这样,如果它在那里得到通知,它就知道不用麻烦去等待事件了。或者我可以使用一个有点粗糙的boolean
标志,该标志在事件进入该状态时立即轮询WAIT\u FOR\u EVENT
以检查事件是否已经触发
然而,我所寻找的是一个更优雅、更健壮的解决方案,以解决这个普遍问题
我已经使用了Android
标记,尽管这可能被认为是一个一般的Java设计模式问题,只是为了防止有更好的解决方案依赖于Android特定的类。我认为做一些工作
和等待事件
可以合并。在“特殊材料”完成之前,不必进行状态转换:
public enum LinkStates implements StuffDoneListener {
// ...
START_SOME_WORK_AND_WAIT {
public void process() {
// ....
someObject.startDoingSpecialStuff();
}
public void onSpecialStuffComplete() {
outerClass.toState(EVENT_IS_COMPLETE);
}
},
EVENT_IS_COMPLETE {
public void process() {
// ...
}
// ...
}
// ...
public void onSpecialStuffComplete() {
}
}
这样写时我看不到竞争条件,所以假设它没有破坏未发布的内容,它应该可以正常工作。是在“UI”线程上调用DO\u SOME\u work.process(与调用“onSpecialStuffComplete”的过程相同)?如果是这样,我看不到比赛条件。如果没有-是否有原因您不能做一些工作。进程颠倒调用顺序,以便在specialStuff启动之前,outerClass正在等待事件?非常感谢。虽然真正的代码要复杂得多,但您让我思考,从概念上讲,我现在有了与此相当类似的东西。这里学到的要点是在选择状态时要小心,首先要通过触发事件并在一个状态内接收后续回调来消除竞争条件。