java.util.ConcurrentModificationException List问题

flexonjava 2013-01-13 11:14:50
程序功能: 主程序 往 List<OldDBPlanVersion2> totalList = new ArrayList<OldDBPlanVersion2>(); 不断放数据。
5个线程不断地消耗数据, 对totalList的操作 通过 syschronized同步。但是程序还抛异常, 从日志看,没有发现有2个线程同时进入对 totalList的操作,不知道具体原因是什么啊。
引用
2013-01-13 11:09:04,042 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,042 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,052 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,052 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,062 ERROR [com.MoveDataCurr] - <in Thread-5>
2013-01-13 11:09:04,062 ERROR [com.MoveDataCurr] - <out Thread-5>
2013-01-13 11:09:04,069 ERROR [com.MoveDataCurr] - <in Thread-1>
2013-01-13 11:09:04,069 ERROR [com.MoveDataCurr] - <out Thread-1>
2013-01-13 11:09:04,080 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,080 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,120 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,120 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,129 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,129 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,162 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,162 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,165 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,165 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,226 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,226 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,278 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,278 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,297 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,297 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,308 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,308 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,349 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,349 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,374 ERROR [com.MoveDataCurr] - <in main>
2013-01-13 11:09:04,374 ERROR [com.MoveDataCurr] - <out main>
2013-01-13 11:09:04,454 ERROR [com.MoveDataCurr] - <in Thread-2>
2013-01-13 11:09:04,456 ERROR [com.MoveDataCurr] - <Thread-2 ......a thread error,size:219>
java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(AbstractList.java:752)
at java.util.SubList.listIterator(AbstractList.java:682)
at java.util.AbstractList.listIterator(AbstractList.java:284)
at java.util.SubList.iterator(AbstractList.java:678)
at java.util.AbstractCollection.contains(AbstractCollection.java:82)
at java.util.AbstractCollection.removeAll(AbstractCollection.java:336)
at com.MoveDataCurr.dealinThread(MoveDataCurr.java:96)
at com.MoveDataCurr.access$0(MoveDataCurr.java:84)
at com.MoveDataCurr$1.run(MoveDataCurr.java:66)
at java.lang.Thread.run(Thread.java:662)



package com;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MoveDataCurr {
List<OldDBPlanVersion2> totalList = new ArrayList<OldDBPlanVersion2>();
Logger log = LoggerFactory.getLogger(MoveDataCurr.class);

AtomicInteger atomic = new AtomicInteger(0);


public static void main(String[] args) throws Exception {

MoveDataCurr md = new MoveDataCurr();
md.moveData();
}

public void moveData() throws Exception {

try {

openThread();
OldDBPlanVersion2 d;
Random rr = new Random();

while (true) {
List<OldDBPlanVersion2> dbList = new ArrayList<OldDBPlanVersion2>();

for (int i = 0; i < 20; i++) {
d = new OldDBPlanVersion2();
dbList.add(d);
}

Thread.sleep(Math.abs(rr.nextInt() % 100));

synchronized (totalList) {
log.error("in " + Thread.currentThread().getName());
totalList.addAll(dbList);
log.error("out " + Thread.currentThread().getName());
}

}

} catch (Exception e) {
log.error("出错", e);
}
while (atomic.get() > 0) {
Thread.sleep(10000);
}

}

private void openThread() {

for (int i = 0; i < 5; i++) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
dealinThread();
} catch (Exception e) {
log.error(
Thread.currentThread().getName()+ " ......a thread error,size:"+ totalList.size() ,
e);
System.exit(-1);

}
atomic.addAndGet(-1);
}
};

atomic.addAndGet(1);
Thread t = new Thread(r);
t.start();
}
}

private void dealinThread() throws Exception {

List<OldDBPlanVersion2> my;
int len;
Random rr = new Random();
while (true) {
my = null;
synchronized (totalList) {
log.error("in " + Thread.currentThread().getName());
len = totalList.size();
if (len > 200) {
my = totalList.subList(0, 200);
totalList.removeAll(my);
} else if (len > 0) {
my = new ArrayList<OldDBPlanVersion2>();
my.addAll(totalList);
totalList.clear();
}
log.error("out " + Thread.currentThread().getName());
}

Thread.sleep(Math.abs(rr.nextInt() % 1000));

}

}

}

class OldDBPlanVersion2 {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

...全文
309 2 打赏 收藏 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
flexonjava 2013-01-13
  • 打赏
  • 举报
回复
谢谢。替换成 Collections.synchronizedList 也是同样的错误。 后来用下面的方法是可行的: List<OldDBPlanVersion2> totalList = new CopyOnWriteArrayList<OldDBPlanVersion2>(new ArrayList<OldDBPlanVersion2>());
Inhibitory 2013-01-13
  • 打赏
  • 举报
回复
ArrayList是非线程安全的,多线程访问一个list,可以先用Collections.synchronizedList方法把list变成一个线程安全的list,然后再对其操作

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧