重新加载表时java.util.ConcurrentModificationException

时间:2014-07-25 13:51:48

标签: java

我的应用程序中有changeTableView方法。该方法使用一组新内容重新加载TableView。它的目的是处理分页。它将重置一个表并用另一个页面的行加载它。

public void changeTableView(int index, int limit) {
    System.out.println("index: " + index + ", limit: " + limit);
    int newIndex = index * limit;

    List<Product> productSubList = allProducts.subList(Math.min(newIndex, allProducts.size()), Math.min(allProducts.size(), newIndex + limit));

    productListTable.getItems().clear();
    productListTable.setItems(null);

    ObservableList<Product> products = FXCollections.observableList(productSubList);
    productListTable.setItems(products);
}

首次使用index = 0初始化时调用该方法,然后通过以下方法调用该方法。

    pagination.currentPageIndexProperty().addListener(new ChangeListener<Number>() {

        @Override
        public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
            changeTableView(newValue.intValue(), limit.get());
            System.out.println("new value: " + newValue.intValue() + ", limit: " + limit.get());
        }
    });
当用户请求不同的页面时,会调用

changed方法。

但是,更改页面会引发以下异常。

java.util.ConcurrentModificationException
    at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)
    at java.util.ArrayList$SubList.size(ArrayList.java:998)
    at com.sun.javafx.collections.ObservableListWrapper.size(ObservableListWrapper.java:335)
    at com.sun.javafx.scene.control.skin.TableViewSkin.getItemCount(TableViewSkin.java:325)
    at com.sun.javafx.scene.control.skin.TableViewSkin.updatePlaceholderRegionVisibility(TableViewSkin.java:561)
    at com.sun.javafx.scene.control.skin.TableViewSkin.updateRowCount(TableViewSkin.java:623)
    at com.sun.javafx.scene.control.skin.TableViewSkin.layoutChildren(TableViewSkin.java:426)
    at javafx.scene.Parent.layout(Parent.java:1018)
    at javafx.scene.Parent.layout(Parent.java:1028)
    at javafx.scene.Parent.layout(Parent.java:1028)
    at javafx.scene.Scene.layoutDirtyRoots(Scene.java:524)
    at javafx.scene.Scene.doLayoutPass(Scene.java:495)
    at javafx.scene.Scene.access$3900(Scene.java:173)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2205)
    at com.sun.javafx.tk.Toolkit$5.run(Toolkit.java:363)
    at com.sun.javafx.tk.Toolkit$5.run(Toolkit.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:361)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:384)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:463)
    at com.sun.javafx.tk.quantum.QuantumToolkit$9.run(QuantumToolkit.java:332)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)

我怀疑这里的罪魁祸首是java.util.ConcurrentModificationException at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)

如何在不影响应用程序性能的情况下阻止这种情况发生?

1 个答案:

答案 0 :(得分:3)

根据文档,sublist()会返回view的{​​{1}}。由于它是List,因此保持它并多次迭代是不安全的。

List.sublist()

相反,您应该在传递之前复制子列表。

Collections.copy