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()
方法是状态更改时调用的方法。每个状态还倾向于覆盖各种侦听器方法以接收各种事件

State
DO\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正在等待事件?非常感谢。虽然真正的代码要复杂得多,但您让我思考,从概念上讲,我现在有了与此相当类似的东西。这里学到的要点是在选择状态时要小心,首先要通过触发事件并在一个状态内接收后续回调来消除竞争条件。