我得到ConcurrentModificationException时添加一个项目



我试图保存不同的经理从collabs到managersId的经理id,但我得到一个异常"ConcurrentModificationException"

public void fillTree() throws SystemException, PortalException {
        TreeNode nodeParent;
        TreeNode nodeFils;
        Set<Long> managersId = new HashSet<Long>();
        UserVO user = new UserVO();
        collabs = CollabLocalServiceUtil.getCollabs(-1, -1);
        Iterator<Long> iter = managersId.iterator();
        long id;
        for (int i = 0; i < collabs.size(); i++) {
            id = collabs.get(i).getManagerId();
            synchronized (managersId) {
                managersId.add((Long) id);
                System.out.println(id);
            }
        }

        while (iter.hasNext()) {
            id = iter.next();//throw exeption
            user = getUserById(id);
            nodeParent = new DefaultTreeNode(user.getFullName(), root);
            for (int j = 0; j < collabs.size(); j++) {
                if (collabs.get(j).getManagerId() == user.getUserId()) {
                    nodeFils = new DefaultTreeNode(getUserById(
                            collabs.get(j).getUserId()).getFullName(),
                            nodeParent);
                }
            }
        }
    }

我正在使用liferay门户

根据问题更新进行编辑

在这段新代码中,问题出在迭代器上。您初始化了迭代器,然后修改了集合,然后尝试使用脏迭代器。这就是并发修改异常的原因。所以这个问题的解决方法很简单。只要把Iterator<Long> iter = managersId.iterator();移到for循环之后。试着
public void fillTree() throws SystemException, PortalException {
    TreeNode nodeParent;
    TreeNode nodeFils;
    Set<Long> managersId = new HashSet<Long>();
    UserVO user = new UserVO();
    collabs = CollabLocalServiceUtil.getCollabs(-1, -1);        
    long id;
    for (int i = 0; i < collabs.size(); i++) {
        id = collabs.get(i).getManagerId();
        synchronized (managersId) {
        managersId.add((Long) id);
        System.out.println(id);
        }
    }
    Iterator<Long> iter = managersId.iterator(); // Getting the new iterator with latest value.
    while (iter.hasNext()) {
        id = iter.next();//Now this wont throw exeption
        user = getUserById(id);
        nodeParent = new DefaultTreeNode(user.getFullName(), root);
        for (int j = 0; j < collabs.size(); j++) {
        if (collabs.get(j).getManagerId() == user.getUserId()) {
            nodeFils = new DefaultTreeNode(getUserById(
                collabs.get(j).getUserId()).getFullName(),
                nodeParent);
        }
        }
    }
}
老回答

首先从你的逻辑,我认为你试图获得唯一的经理id作为列表。在这种情况下,您可以使用Set

对于你当前的问题,如果它在多线程环境中执行,你可以使用同步块,如

List<Long> managersId = new ArrayList<Long>();
collabs = CollabLocalServiceUtil.getCollabs(-1, -1);
long id;
for (int i = 0; i < collabs.size(); i++) {
    id = collabs.get(i).getManagerId();
    synchronized (managersId) {
        if (!managersId.contains(id)) {
            managersId.add((Long) id);
        }
    }
}

或者可以使用java.util.concurrent.CopyOnWriteArrayList进行并发列表操作

List<Long> managersId = new CopyOnWriteArrayList<Long>();

作为第三种选择,你可以让一个普通的列表通过集合类

同步
Collections.synchronizedList(managersId);

相关内容

  • 没有找到相关文章

最新更新