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,不知道为什么会出现这种问题。
请大家帮忙分析分析

解决方案 »

  1.   

    有没有其他线程操作了你的productViewCount?
      

  2.   

    我看你最后些了providerViewCount.put(userId, uViewCount);了那么我猜想你在遍历provier的时候是不是remove了productViewCount
      

  3.   


    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()方法只有一个线程在定时调用
      

  4.   


    我的代码里没有调用remove方法
    只有清空MAP的clear()方法
      

  5.   

    可能就是因为你遍历的时候另一个线程调用了productViewCount.put的原因
      

  6.   

    你的例子好比就是以下代码
    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");
    }
      

  7.   

    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);那意思是说这样可以解决问题吗?  还是需要在那里枷锁呢?
      

  8.   

    显然是不行的。。
    凡是用到productViewCount 的时候都同步
    synchronized(productViewCount ) {
      //操作
    }
      

  9.   


    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