我正在实施自定义MapReduce(对于学校,所以请不要建议使用Hadoop或现有解决方案),我遇到的问题是在Map和Reduce阶段之间“存储”中间数据。
我正在考虑使用ConcurrentHashMap,CHM_key == Map's_Key,并且它的值是包含Map's_Key上关联的所有Map's_values的Arraylist,因此reduce可以简单地聚合这些值。
但是,我想不出一种方法可以原子地改变CHM的Arraylist实例,而不会锁定整个集合。
我理解这个集合实现了putifAbsent和replace方法;实际上putifAbsent很有用,因为如果键不存在我只需要放一个新的ArrayList就可以了。
然而......替换Arraylist并不是那么简单,因为我必须获取它,添加新值,然后替换它,如果不锁定整个集合就无法原子地完成...
答案 0 :(得分:0)
如果有人有兴趣我找到了解决方案,在这种情况下实际上非常简单;你只需锁定价值!
public class MapReduceDictionary extends ConcurrentHashMap<String, ArrayList<Integer>>{
private static final long serialVersionUID = 1L;
public void addValue(String key, int value) throws InterruptedException {
ArrayList<Integer> absentArr = new ArrayList<Integer>();
absentArr.add(value);
if (putIfAbsent(key, absentArr) == null) return;
synchronized (get(key)) {
get(key).add(value);
}
}
}
我对此进行了修改并且似乎有效,但如果您对此失败有任何评论,请告诉我!