3

仅供参考,我在 Swing on Java 中为我的 GUI 采用了中介者模式。

不幸的是,如果用户输入需要新窗口,则总是会引发并发修改异常。

这是因为我的代码在处理来自现有同事(窗口)的用户输入的过程中,尝试将新同事(新窗口)添加到调解员的同事列表中。

例如

public MainScreenColleague implements GuiColleague, ActionListener {
    private GuiMediator mediator;
    public MainScreenColleague(GuiMediator medi) {
        mediator = medi;
        // implement JFrame with JButtons
    }
    public conveyInputToMediator(EventObject event) {
        mediator.conveyInputToColleagues(event);
    }
    public receiveInputFromMediator(EventObject event) {
        if (event.getSource() = particularBtn) {
            GuiColleague particularColleague = new ParticularConcreteColleague(mediator);
            //THIS IS THE CODE THAT THROWS CONCURRENCY EXCEPTION
            mediator.addGuiColleague(particularColleague);
        }       
}

是否有其他一些我可以采用的处理添加新同事的结构?提前感谢您的任何建议或想法。

4

2 回答 2

1

一种选择可能是采用 Swing-esque 模型,并让您的中介存储一个“事件队列”,以便在适当的时候进行更新。这样,当您在处理来自其他对象的事件时添加新窗口时,该窗口不会混淆逻辑。它只是被添加到“完成后处理”队列中,该队列在调解完成后得到处理。

另一种选择是在迭代之前制作列表的副本,以便在迭代期间对原始结构所做的更改不会显示在被迭代的列表中。

另一个想法是使用一些非迭代器技术来访问元素。例如,如果您将窗口存储在一个列表中,您可以使用这样的 for 循环:

for (int i = 0; i < elems.size(); ++i)
    /* ... */

这不会抛出这些异常。

于 2011-02-04T23:36:21.120 回答
1

如果遍历的次数远远超过修改次数,那么像CopyOnWriteArrayList这样的写时复制数据结构可能适合。

于 2011-02-04T23:48:36.523 回答