HashMap多线程问题,坐等讨论

goInfall 2015-06-17 05:49:04
最近修复了一个bug,是由于hashMap的多线程引起的,现把问题简单化,想听听各位大神的见解!
MainClass:
public class MainClass {
public static void main(String[] args) throws InterruptedException {
for(int i = 0;i<100;i++){
Thread t = new Thread(new TaskRunnable(i)); //启动一百个线程测试
t.start();
}
}
}

TaskRunnable:
public class TaskRunnable implements Runnable{
private int operationNumber;
public TaskRunnable(int a){
this.operationNumber = a;
}
@Override
public void run() {
Action action = new Action();
Bean bean = action.getAndUpdateBeanFromCache();
System.out.println("threadId is id = " + Thread.currentThread().getId());
if(bean==null){
bean = new Bean();
bean.setUserId("12344");
bean.setCount(11);
}
Map<String,String> map = bean.getMap();
map.put(operationNumber+"",operationNumber+"");
System.out.println("map key = " + operationNumber + " ," + " value = " + operationNumber);
RedisUtil.setCache(RedisConstant.testKey, new Gson().toJson(bean));
}
}

Action:
public class Action {
public Bean getAndUpdateBeanFromCache(){
Bean bean = new Bean();
String key = RedisConstant.testKey;
String value = RedisUtil.getCache(key);
Type type = new TypeToken<Bean>(){}.getType();
bean = new Gson().fromJson(value,type);
return bean;
}
}


我的测试结果如下:
{"map":{"0":"0","79":"79","86":"86"},"userId":"123456","count":0},每次map都不同
想听听各位大声关于最后Redis中存储的Bean的map是多少?
...全文
227 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
goInfall 2015-06-25
  • 打赏
  • 举报
回复
引用 4 楼 oZhiMing12 的回复:
对头用户并发包中的 concurrentHashMap 应该锁的粒度比较小,而且对map的访问速度基本上无影响....
你说的这个再生产环境没试过,但是concurrentHashMap同样会出现结果不一致的问题,所以最后比没有考虑这个方案
seqwait 2015-06-25
  • 打赏
  • 举报
回复
对头用户并发包中的 concurrentHashMap 应该锁的粒度比较小,而且对map的访问速度基本上无影响....
goInfall 2015-06-18
  • 打赏
  • 举报
回复
引用 2 楼 finemi 的回复:
java默认的所有集合都是非线程安全的,包括HashMap,考虑使用同步块或同步方法或者Lock 或者使用:Collections.synchronizedMap(map);将一个普通map对象包装成线程安全的map对象后使用
前提是这个实际情况中,访问时PV级别的 1.加同步控制,会降低访问速度,用户体验不好。 2.用concurrentHashMap也会出现同样的问题。
finemi 2015-06-18
  • 打赏
  • 举报
回复
java默认的所有集合都是非线程安全的,包括HashMap,考虑使用同步块或同步方法或者Lock 或者使用:Collections.synchronizedMap(map);将一个普通map对象包装成线程安全的map对象后使用
goInfall 2015-06-17
  • 打赏
  • 举报
回复
没有人回答,自己顶上!

81,092

社区成员

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

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