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);}

0 0
原创粉丝点击