【问题标题】:How to refresh other users Vaadin Table without causing Concurrent Modification Exception?如何在不引起并发修改异常的情况下刷新其他用户 Vaadin 表?
【发布时间】:2013-09-23 00:10:48
【问题描述】:

用例: 用户登录并打开 Vaadin 表组件,显示约会状态。每行都有一个下拉菜单(组合框)来更改状态(已安排、已到达、已审核)。现在多个用户已经在自己的浏览器中打开了这个表,并且不断地更改约会状态。这些更改应反映在所有打开的表上,即如果用户 A 更改约会 appt-1 的状态,它会反映并刷新当前打开的所有表。

之前我们使用 ICE-PUSH 插件应用了基于事件的刷新,即如果在 PC-1 上进行了更改(即应用程序实例 a1),我从 MainApplication 类的静态 CopyOnWriteArrayList 获取 Vaadin 应用程序的其他实例,并且通过那个实例,我调用loadTable 函数。之后,我调用 ICEPUSH 将新的更改推送给所有用户。

public class MainApplication extends Application {
    public static CopyOnWriteArrayList<MainMedMaxApplication> appList=new CopyOnWriteArrayList<MainMedMaxApplication>();

    @Override
    public void init() {
        setMainWindow(new Window("APPointment Dashboard"));
        getMainWindow().setContent(mainLayout);
        setMainComponent(getCustomTable());
        //Custome Table make table . it also register listeners over table.
        //loadTable will load the table. 
        loadTable()
        appList.add(this);  
    } 
}

public void loadTabl(String date) {
    //this will reload the table component By Querying database
}
private void registerlistener() {
    table.addListeners()
        {
        //do any change to table in this instance and save it to db then call ICE push so it can referesh all app instances by getting from applist.
        synchronizePortlets();
        }
}
public void synchronizePortlets() {
    // TODO Auto-generated method stub
    Iterator<MainApplication>itM = appList.iterator();
    while(itM.hasNext()) {
        MainApplication app = itM.next();
        app.loadTabl();
        app.getPusher().push();
    }
}
}

这工作正常,但在某些情况下,当进行许多频繁更改时,并发修改异常会上升。那么是否有人可以帮助改进这一点?

我在此之后考虑的解决方案是通过其自己的应用程序实例在每 1 分钟内强制而不是连续地刷新表格组件。这将查询数据库并使用更新的状态重新加载表容器。为此,我使用 Refresher 插件,但它引发了一个异常,即ConcurrentModificationException,因为有时用户还通过更改表中的组合状态来更改表组件,同时刷新器刷新表,这里引发并发修改异常。所以我正在考虑从用户的角度冻结表格组件,这样用户就不能做任何事情,并且在后台可以轻松刷新表格。

如果对于这个用例你们有更好的解决方案,请告诉我。我很感激你。

使用 Vaadin 6.8.12、java 1.7、apache Tomcat 7.42

【问题讨论】:

    标签: multithreading user-interface web vaadin icepush


    【解决方案1】:

    Vaadin 6

    您需要应用同步,因为您正在从另一个线程对 GUI 进行更改(我认为使用 Refresher 或 IcePush 并不重要,我认为在这两种情况下您都将使用另一个线程)。在Application 实例上同步。

    在 Vaadin 论坛上查看 this post

    Vaadin 7

    编辑:我鼓励您升级到 Vaadin 7.1 并在 UIUI#access 上使用这种新方法,推荐 here

    【讨论】:

    • 你可以看到我们在数组列表上使用副本,在我的理解中是线程安全的
    • 到目前为止,我们已经使用了很多解决方案,但是在使用 Synchronize 块时,它会导致应用程序没有响应,红色圆圈开始旋转,应用程序进入死锁或异常
    • @Mubasher 既然这类问题应该在 Vaadin 7 中得到妥善解决,您是否考虑过升级?升级还有很多其他优势。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多