java.util.ConcurrentModificationException的异常

potahai 2010-05-24 10:18:10

public final static int MAP_INIT_CAPACITY = 100000;
public static Map<Integer, Integer> productViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
public static Map<Integer, Integer> providerViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
//每一分钟调用一次flush()
public static void flush() {
ViewCountLogic viewCountLogic = new ViewCountLogic();

Iterator productViewCountIter = productViewCount.keySet().iterator();
while(productViewCountIter.hasNext()) {

Integer productId = (Integer)productViewCountIter.next();//这里抛出异常
Integer viewCount = productViewCount.get(productId);
viewCountLogic.incProductViewCount(productId, viewCount);


ProductLogic productLogic=new ProductLogic();
Product product = productLogic.getProductAllById(productId);
int userId = product.getUserId();
int uViewCount = viewCount;
if(providerViewCount.containsKey(userId)) {
uViewCount += providerViewCount.get(userId);
}
providerViewCount.put(userId, uViewCount);
}


Iterator userViewCountIter = providerViewCount.keySet().iterator();
while(userViewCountIter.hasNext()) {
Integer userId = (Integer)userViewCountIter.next();
Integer viewCount = providerViewCount.get(userId);
viewCountLogic.incUserViewCount(userId, viewCount);
}

productViewCount.clear();
providerViewCount.clear();
productViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
providerViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
}


查了一些资料,这种时候会抛出java.util.ConcurrentModificationException的异常


Iterator<MonthlyStatData> it = papers.iterator();
while (it.hasNext()) {
MonthlyStatData data = it.next();
if (data.getValue == 0 ) {
papers.remove(data);
}
}



上面的代码是说有个月统计的List, 里面有部分统计数据是0, 不想让出现,于是就迭代遍历,删除统计数据是0的数据. 但是上面的代码会导致ConcurrentModificationException, 正确的应该是:

Iterator<MonthlyStatData> it = papers.iterator();
while (it.hasNext()) {
MonthlyStatData data = it.next();
if (data.getValue == 0 ) {
it.remove();
papers.remove(data);
}
}


但是我的代码中并没有去remove什么 直接都是重新获得一个Iterator,不知道为什么会出现这种问题。
请大家帮忙分析分析
...全文
175 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
potahai 2010-05-25
  • 打赏
  • 举报
回复
晕了,为什么只有一个人
龙四 2010-05-24
  • 打赏
  • 举报
回复
显然是不行的。。。。。


凡是用到productViewCount 的时候都同步
synchronized(productViewCount ) {
//操作
}

[Quote=引用 7 楼 potahai 的回复:]

Java code
public static synchronized Map<Integer, Integer> productViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
public static synchronized Map<Integer, Integer> providerViewCount……
[/Quote]
potahai 2010-05-24
  • 打赏
  • 举报
回复
我对该在哪个地方枷锁比较茫然!!!!
potahai 2010-05-24
  • 打赏
  • 举报
回复
public static synchronized Map<Integer, Integer> productViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
public static synchronized Map<Integer, Integer> providerViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);


那意思是说这样可以解决问题吗? 还是需要在那里枷锁呢?


龙四 2010-05-24
  • 打赏
  • 举报
回复
你的例子好比就是以下代码


Map<String, String> map = new HashMap<String, String>();
map.put("1", "1");
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
Map.Entry<String, String> entry = null;
while((entry = iterator.next()) != null) {
map.put("2", "2");
}
龙四 2010-05-24
  • 打赏
  • 举报
回复
可能就是因为你遍历的时候另一个线程调用了productViewCount.put的原因
potahai 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ticmy 的回复:]

我看你最后些了providerViewCount.put(userId, uViewCount);了

那么我猜想你在遍历provier的时候是不是remove了productViewCount
[/Quote]

我的代码里没有调用remove方法
只有清空MAP的clear()方法
potahai 2010-05-24
  • 打赏
  • 举报
回复

public static void incProductViewCount(int productId) {
if(productViewCount.containsKey(productId)) {
int viewCount = productViewCount.get(productId) + 1;
productViewCount.put(productId, viewCount);
} else {
productViewCount.put(productId, 1);
}
}


public static void incProviderViewCount(int userId) {
if(providerViewCount.containsKey(userId)) {
int viewCount = providerViewCount.get(userId) + 1;
providerViewCount.put(userId, viewCount);
} else {
providerViewCount.put(userId, 1);
}
}


这个在页面上随时都会被调用,而flush()方法只有一个线程在定时调用
龙四 2010-05-24
  • 打赏
  • 举报
回复
我看你最后些了providerViewCount.put(userId, uViewCount);了

那么我猜想你在遍历provier的时候是不是remove了productViewCount
龙四 2010-05-24
  • 打赏
  • 举报
回复
有没有其他线程操作了你的productViewCount?
potahai 2010-05-24
  • 打赏
  • 举报
回复
不要沉啊
potahai 2010-05-24
  • 打赏
  • 举报
回复

public final static int MAP_INIT_CAPACITY = 100000;
public static Map<Integer, Integer> productViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
public static Map<Integer, Integer> providerViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);

/*
*
*/
public static void incProductViewCount(int productId) {
if(productViewCount.containsKey(productId)) {
int viewCount = productViewCount.get(productId) + 1;
productViewCount.put(productId, viewCount);
} else {
productViewCount.put(productId, 1);
}
}

/*
*
*/
public static void incProviderViewCount(int userId) {
if(providerViewCount.containsKey(userId)) {
int viewCount = providerViewCount.get(userId) + 1;
providerViewCount.put(userId, viewCount);
} else {
providerViewCount.put(userId, 1);
}
}

/*
*
*/
public static void flush() {
ViewCountLogic viewCountLogic = new ViewCountLogic();

Iterator productViewCountIter = productViewCount.keySet().iterator();
while(productViewCountIter.hasNext()) {

Integer productId = (Integer)productViewCountIter.next();
Integer viewCount = productViewCount.get(productId);
viewCountLogic.incProductViewCount(productId, viewCount);


ProductLogic productLogic=new ProductLogic();
Product product = productLogic.getProductAllById(productId);
int userId = product.getUserId();
int uViewCount = viewCount;
if(providerViewCount.containsKey(userId)) {
uViewCount += providerViewCount.get(userId);
}
providerViewCount.put(userId, uViewCount);
}


Iterator userViewCountIter = providerViewCount.keySet().iterator();
while(userViewCountIter.hasNext()) {
Integer userId = (Integer)userViewCountIter.next();
Integer viewCount = providerViewCount.get(userId);
viewCountLogic.incUserViewCount(userId, viewCount);
}

productViewCount.clear();
providerViewCount.clear();
productViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
providerViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);
}


这些方法和变量中都需要在哪里加synchronized? 请指点1,2

67,549

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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