多用户访问此代码时发生java.util.ConcurrentModificationException
下面是我的代码抛出多用户访问此代码时发生java.util.ConcurrentModificationException,java,exception-handling,Java,Exception Handling,下面是我的代码抛出java.util.ConcurrentModificationException,它是从servlet执行的 当多个用户尝试访问此代码时发生异常,异常位于此行: 对于(消息消息消息:dayWiseMsgs) 代码: List<Message> newMessages = Collections.synchronizedList( new LinkedList<Message>()); try{ logger.debug("L
java.util.ConcurrentModificationException
,它是从servlet执行的
当多个用户尝试访问此代码时发生异常,异常位于此行:
对于(消息消息消息: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;
List newMessages=Collections.synchronizedList(
新建LinkedList());
试一试{
logger.debug(“Last Message Id=“+lastMessageId+
“对于聊天室=“+this.getName());
List allMessages=新建链接列表(
getMessages().values());
对于(列出DayWiseMSG:allMessages){
对于(消息消息消息:dayWiseMsgs){
newMessages.add(msg);
this.setLastPushMessageId(msg.getId());
}
}
}
}
allMessages=null;
}捕获(例外e){
e、 printStackTrace();
}
返回新消息;
当遍历列表时,通常会抛出ConcurrentModificationException
,同时通常会有另一个线程或甚至是同一个循环尝试修改(添加/删除)列表的内容
现在您有了通过调用集合来同步的新消息的列表。synchronizedList
但是您没有使所有消息
同步,而是使用新消息
创建它。发生在集合
将被更改时,而一些线程正在使用迭代器对其进行遍历,在多线程
以及单线程
环境中可能发生这种情况
谈到您的代码,当一个线程正在创建同步的新消息时,可能会发生这种情况:
List<Message> newMessages = Collections.synchronizedList(
new LinkedList<Message>());
在方法级别移动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;
}
我已经用for循环和synchronized解决了这个问题:
我所做的是:将foreach循环替换为simple for并修改列表的创建,使其同步:
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());
}
}
}
}
chatRoom.getMessages().put(key,Collections.synchronizedList(newarraylist());
List allMessages=newlinkedlist(getMessages().values());
对于(列出DayWiseMSG:allMessages){
//List dayMsgs=新链接列表(dayWiseMsgs);
if(lastMessageIdlastMessageId){
newMessages.add(msg);
this.setLastPushMessageId(msg.getId());
}
}
}
}
为什么要在同一个列表中添加for
循环和迭代器
?getMessages()的类型是什么?
?它是从多个线程访问/修改的吗?getMessages()这是一个映射,关于这个列表
它只包含消息
类,为什么您要再次迭代它?请指定标题-让它更像问题。我尝试了这个解决方案,但仍然出现异常,有一段时间它在同一行抛出NullPointerException:for(消息:dayWiseMsgs)
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
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());
}
}
}
}