在基于枚举的有限状态机中避免竞争条件

时间:2014-08-29 21:50:12

标签: java android state-machine

我有一个基于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的类。

1 个答案:

答案 0 :(得分:1)

我认为DO_SOME_WORKWAIT_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() {
    }
}

当用这种方式编写时,我没有看到竞争条件,所以假设它没有破坏未发布的东西,它应该可以正常工作。