HashMap进行put操作时遇到的并发问题
来源:互联网 发布:怎么开农村淘宝服务站 编辑:程序博客网 时间:2024/05/20 11:25
转自:http://blog.csdn.net/jiangguilong2000/article/details/12997621
今天遇到了个问题,在全局服务器重启的时候,原有的4游戏逻辑服务器会马上再注册过来,通过多线程对HashMap进行操作,结果从后续的日志发现,id=1的数据丢失了。查了一下原因,多线程环境下put还是可能会有问题 .
2013-10-22 18:59:55.098 INFO [pool-5-thread-3] - 注册房间开始 id=1,type=pve1003,ip=115.29.172.234,port=10104,count=0
2013-10-22 18:59:55.098 INFO [pool-5-thread-5] - 注册房间开始 id=3,type=pve1004,ip=115.29.172.234,port=10105,count=0
2013-10-22 18:59:55.098 INFO [pool-5-thread-4] - 注册房间开始 id=2,type=pvp1001,ip=115.29.172.234,port=10101,count=0
2013-10-22 18:59:55.099 INFO [pool-5-thread-1] - 注册房间开始 id=4,type=pve1002,ip=115.29.172.234,port=10103,count=0
2013-10-22 18:59:55.102 INFO [pool-5-thread-3] - 注册房间完成 id=1
2013-10-22 18:59:55.103 INFO [pool-5-thread-4] - 注册房间完成 id=2
2013-10-22 18:59:55.104 INFO [pool-5-thread-5] - 注册房间完成 id=3
2013-10-22 18:59:55.105 INFO [pool-5-thread-1]- 注册房间完成 id=4
void addEntry(int hash, K key, V value, int bucketIndex) { Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<K,V>(hash, key, value, e); if (size++ >= threshold) resize(2 * table.length); }
发生在index相同的情况下,大家拿到的链头可能不是最新的,后一个会直接覆盖了前一个
而且当多条线程检测到容量超过负载因子时,会能发生多次resize。
小结一下:remove与put都是一样的,由于大家拿到的不是最新链头,只要大家在Entry数组的index相同时(经过hash后的index),就有可能出现后一个覆盖前一个的操作,即前一个的操作无效。
可能产生的现象会是:
1)put进行的data有可能丢失了
2)一些通过remove(Object key)删除掉的元素(返回删除成功)又出来了。
3)多线程检测到HashMap容量超过负载因子时会进行多次的resize,由于要rehash,所以消耗的性能也是巨大的。
考虑到这个方法只有在起服务器的时候会用到,而且,后续的关于rooms和areas的map读操作比较频繁,所以通过加同步块解决,比较合适!
// Room缓存 角色Id -- Room对象private final Map<Integer, Room> rooms = new HashMap<Integer, Room>();private final Map<String, List<Integer>> areas = new HashMap<String, List<Integer>>();public synchronized Room registRoom(Channel channel, String type, int port,String clientIp, List<PlayerDTO> playerList) {List<Integer> list = areas.get(room.getType());if (null == list) {list = new ArrayList<Integer>();areas.put(room.getType(), list);}rooms.put(room.getId(), room);}
- HashMap进行put操作时遇到的并发问题
- HashMap进行put操作时遇到的并发问题
- 关于hashmap put 的问题
- HashMap的并发问题
- java HashMap的put
- HashMap的put()方法
- HashMap并发出现的问题
- 项目中遇到的[数据库并发]操作问题
- Loadrunner 进行SOCKET并发测试遇到问题
- HashMap的put源码解析
- hibernate中进行update操作遇到的问题
- 最近遇到的并发问题
- 并发请求遇到的问题
- 阅读HashMap——jdk7时遇到的问题记录
- JAVA HASHMAP并发访问出现的问题
- 在SAE开放云平台进行IO读写相关操作时遇到的问题
- 使用 通用mapper时 根据主键进行 删除 更新操作 遇到的问题
- HashMap常见并发问题
- jacob语法总结
- Android 开发环境搭建(Linux下)
- phpstorm中实现CI框架(转载)
- Struts2配置详解_配置Action
- CString 和string的互相转换
- HashMap进行put操作时遇到的并发问题
- POJ 1930 无限循环小数化分数&& HDU 2136
- jQuery内核解析
- UITextField检测汉字变化
- java调用com组件操作word使用总结(jacob)
- java学习总结——第三天
- EhLib DBGridEh组件在Delphi中应用全攻略总结
- {A} + {B}
- Predicate Format String Syntax