多个用户访问此代码时发生java.util.ConcurrentModificationException

时间:2015-07-22 05:57:17

标签: java exception-handling

下面是我的代码抛出java.util.ConcurrentModificationException,它正在从servlet执行。

多个用户尝试访问此代码时发生异常,异常就在此行:

for(Message msg:dayWiseMsgs)

代码:

List<Message> newMessages = Collections.synchronizedList(
        new LinkedList<Message>());

try{

    logger.debug("Last Message Id = " + lastMessageId + 
            " For Chat Room=" + this.getName());

    List<List<Message>> allMessages = new LinkedList<List<Message>>(
            getMessages().values());


    for (List<Message> dayWiseMsgs : allMessages) {
         for(Message msg : dayWiseMsgs){
                    newMessages.add(msg);
                    this.setLastPushMessageId(msg.getId());                 
                }
            }        
        }
    }

    allMessages=null;

} catch(Exception e){
    e.printStackTrace();
}

return newMessages;

3 个答案:

答案 0 :(得分:1)

ConcurrentModificationExceptionCollection将被更改而某些线程使用iterator遍历它时会发生multithreaded,这可能发生在single threaded以及newMessages的情况下环境。

谈到你的代码,当1个线程创建synchronized List<Message> newMessages = Collections.synchronizedList( new LinkedList<Message>()); 时,就会发生这种情况:

newMessages.add(msg);

而其他人在其中添加元素:

synchronized

在方法级别移动public synchronized List<Message> test() { List<Message> newMessages = new LinkedList<Message>(); try { logger.debug("Last Message Id = " + lastMessageId + " For Chat Room=" + this.getName()); List<List<Message>> allMessages = new LinkedList<List<Message>>( getMessages().values()); for (List<Message> dayWiseMsgs : allMessages) { if (CollectionUtils.isNotEmpty(dayWiseMsgs) && lastMessageId < dayWiseMsgs.get( dayWiseMsgs.size() - 1).getId()) { for(Message message : dayWiseMsgs){ if (message!= null && message.getId() > lastMessageId) { newMessages.add(message); this.setLastPushMessageId(message.getId()); } } } } allMessages = null; } catch (Exception e) { e.printStackTrace(); } return newMessages; } 关键字可能对您有用:

classpath

<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency>

中添加以下依赖项
replace

答案 1 :(得分:0)

在遍历列表时通常抛出ConcurrentModificationException,同时通常另一个线程甚至同一个循环尝试修改(添加/删除)列表的内容。

现在您已通过调用newMessages获得了已同步的Collections.synchronizedList列表 但是你没有使allMessages同步,你使用newMessages创建它。

答案 2 :(得分:0)

我使用for循环和synchronized来解决它:

我所做的是:用简单的for替换foreach循环并修改list的创建,使其同步:

chatRoom.getMessages().put(key, Collections.synchronizedList(new ArrayList<Message>()));



      List<List<Message>> allMessages =new LinkedList<List<Message>>(getMessages().values());

        for (List<Message> dayWiseMsgs : allMessages) {
            //List<Message> dayMsgs = new LinkedList<Message>(dayWiseMsgs);
            if (lastMessageId < dayWiseMsgs.get(dayWiseMsgs.size() - 1).getId()) {
                //for (Message msg : dayWiseMsgs) {
                Message msg = null;
                for(int i =0 ; i < dayWiseMsgs.size() ; i++){
                    msg = dayWiseMsgs.get(i);
                    if (msg.getId() > lastMessageId ) {
                        newMessages.add(msg);
                        this.setLastPushMessageId(msg.getId());

                    }
                }

            }
        }