我试图保存不同的经理从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);