前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >问题帖子--Concurrent Read/Write Map

问题帖子--Concurrent Read/Write Map

作者头像
李海彬
发布2018-03-23 16:57:20
7950
发布2018-03-23 16:57:20
举报
文章被收录于专栏:Golang语言社区Golang语言社区

DK1.5 引入了 concurrent package, 提供了更多的concurrent 控制方法。 还提供了一个 ConcurrentHashMap 类。从API上看,是可以读写同步。多个thread可以同时读取,一个thread写的时候,其他thread都不能读写。 这是一个用处很广、很方便的类。我想,能不能在 jdk1.4 及以下版本也提供一个。于是查看了 ConcurrentHashMap的代码。 我本以为,实现思路应该是用到了 ReadWriteLock. 大致是这样的思路。

Java代码

// my guess 
class CocurrentHashMap  
{  
Private Map map = null;  
final ReadWriteLock rwLock = new …. ;  
final Lock readLock = rwLock.readLock();;  
final Lock writeLock = rwLock.writeLock();;  
 
// decorate the map as concurrent 
public CocurrentHashMap(Map m);{  
   map = m;  
}  
 
// all write method, like put, putAll, remove, clear 
public void putAll(Map m);{  
   writeLock.lock();;  
 try{  
      map.putAll(m);;  
   }finally{  
      writeLock.unlock();;  
   }  
}  
 
// all read method. like get, containsKey, containsValue, entrySet(); 
public Object get(Object key);{  
   readLock.lock();;  
 try{  
 return map.get(key);;  
   }finally{  
      readLock.unlock();;  
   }  
};  
 
// as we can see, in such places it is convenient to use AOP here. :-);  
 


看了java 1.5 code,才知道不是这样。ConcurrentHashMap是一个比较复杂的类,自己实现了Lock。 
不过也无妨,上面的思路很简单,我也可以找到 third party concurrent.jar, 按照上面自己的猜测思路为 jdk1.4 (and below) 写一个concurrent map. 

这时候,我又想到。Read Lock也是lock。而某些情况下,只是初始化或者 refresh的时候,map 需要write,大多数情况下,都是 read。能不能继续减少 Read Lock 的 overhead? 
我采取了这样一个思路。维护两个 map.  一个是 map to read,  read only.  一个是 map to write,  write only. 
当用户使用 read method 的时候,就用 map to read ; 当用户使用 write method的时候,就写入到 map to write,之后还要copy 一份map to write ,然后把这个copy 赋给map to read。 
所以,read 的时候,非常快,几乎没有 overhead。而write的时候,非常 expensive, 每次write完之后,都要 copy 一遍。所以,建议尽量使用 putAll() method。 
这个思路还有一点不利,就是 同时维护两个同样的entry 的 map. 空间上的效率不是很好,虽然,key, value pair都是object reference, 但map 的entry set结构要有两份。 
代码如下。为了效率,没有用AOP。:-) 

Java代码  
?
/* 
 * Read Write Map 
 *  
 * Write is expensive. 
 * Read is fast as pure HashMap. 
 * 
 * Note: extra info is removed for free use 
 */ 
package net.sf.map;  
 
import java.util.Collection;  
import java.util.Map;  
import java.util.Set;  
import java.util.HashMap;  
import java.util.Collections;  
 
public class ReadWriteMap implements Map {  
 protected volatile Map mapToRead = Collections.unmodifiableMap(getNewMap(););;  
 protected final Map mapToWrite = Collections.synchronizedMap(getNewMap(););;     
 
 // you can override it as new TreeMap();; 
 protected Map getNewMap();{  
 return new HashMap();;  
    }  
 
 // copy mapToWrite to mapToRead 
 protected void sync();{  
        Map newMapToRead = getNewMap();;  
        newMapToRead.putAll(mapToWrite);;  
        mapToRead = Collections.unmodifiableMap(newMapToRead);;  
    }  
 
 // read methods 
 public int size(); {  
 return mapToRead.size();;  
    }  
 public boolean isEmpty(); {  
 return mapToRead.isEmpty();;  
    }  
 
 public boolean containsKey(Object key); {  
 return mapToRead.containsKey(key);;  
    }  
 
 public boolean containsValue(Object value); {  
 return mapToRead.containsValue(value);;  
    }  
 
 public Collection values(); {  
 return mapToRead.values();;  
    }  
 
 public Set entrySet(); {  
 return mapToRead.entrySet();;  
    }  
 
 public Set keySet(); {  
 return mapToRead.keySet();;  
    }  
 
 public Object get(Object key); {  
 return mapToRead.get(key);;  
    }  
 
 // write methods 
 public void clear(); {  
        mapToWrite.clear();;  
        sync();;  
    }  
 
 public Object remove(Object key); {  
        Object o = mapToWrite.remove(key);;  
        sync();;  
 return o;  
    }  
 
 public Object put(Object key, Object value); {  
        Object o = mapToWrite.put(key, value);;  
        sync();;  
 return o;  
    }  
 
 public void putAll(Map t); {  
        mapToWrite.putAll(t);;  
        sync();;  
    }  
}  


希望这段代码能够帮助 有类似需求的人。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-01-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档