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,不知道为什么会出现这种问题。
请大家帮忙分析分析
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()方法只有一个线程在定时调用
我的代码里没有调用remove方法
只有清空MAP的clear()方法
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");
}
public static synchronized Map<Integer, Integer> providerViewCount = new HashMap<Integer, Integer>(MAP_INIT_CAPACITY);那意思是说这样可以解决问题吗? 还是需要在那里枷锁呢?
凡是用到productViewCount 的时候都同步
synchronized(productViewCount ) {
//操作
}
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