我有一个基于enum
的状态机。以下是用于说明我的状态结构和我遇到的问题的示例代码。
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()
方法是状态更改时调用的方法。每个状态还倾向于覆盖各种侦听器方法以接收各种事件。
状态DO_SOME_WORK
调用对象上的方法(startDoingSpecialStuff()
)以使其执行一些冗长的工作。该对象在另一个非UI Thread
上工作。完成后,将通过onSpecialStuffComplete()
通知状态机,该WAIT_FOR_EVENT
在调用工作的原始线程上调用。这里显而易见的问题是,如果工作快速完成,可能存在竞争条件,即在侦听器回调被触发后FSM进入onSpecialStuffComplete()
。
对我来说,修复'这是非常重要的。这可能也会覆盖DO_SOME_WORK
中的WAIT_FOR_EVENT
,这样如果它在那里得到通知就知道不要去boolean
。或者我可以使用一个稍微粗略的WAIT_FOR_EVENT
标志,Android
一旦进入该状态就进行轮询以检查事件是否已经被触发。
然而,我正在寻找的是这个一般性问题的更优雅,更强大的解决方案。
我已经使用了{{1}}标记,即使这可以被视为一般的Java设计模式问题,以防万一有更好的解决方案,我可以使用它依赖于特定于Android的类。
答案 0 :(得分:1)
我认为DO_SOME_WORK
和WAIT_FOR_EVENT
可以合并。在“特殊内容”完成之前,不必进行状态转换:
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() {
}
}
当用这种方式编写时,我没有看到竞争条件,所以假设它没有破坏未发布的东西,它应该可以正常工作。