![](/img/trans.png)
[英]Java Concurrent - Thread synchronization in Fork/Join - LU decomposition
[英]Java fork join concurrent HashMap solve lost updates
我有一个用户列表,每个用户都有一个他访问过的地方序列(例如list = 1,2,3,1,2,8,10,1 ... usw。)。 现在,我想弄清楚每个地方的访问频率。 此外,我真的很想为此加入/加入。 现在,我的主要问题是,您知道在这里使用并发HashMap的方法吗,因为当前的问题是在以下位置丢失了更新
map.put(i, map.get(i)+1);// lost updates here
您是否有一个好主意来解决这个问题,而无需锁定整个地图(地图的某些部分是否像put()一样具有部分锁定?)。 我知道,我可以为每个用户创建一个地图,然后再次加入他们,但我认为,也许有人可以找到更好的解决方案。
public class ForkUsers extends RecursiveAction{
ArrayList<User>users;
ConcurrentHashMap<Integer,Integer>map;
int indexfrom;
int indexto;
ForkUsers(ArrayList<User>users,ConcurrentHashMap<Integer,Integer> map,int indexfrom,int indexto){
this.users=users;
this.map=map;
this.indexfrom=indexfrom;
this.indexto=indexto;
}
void computeDirectly(User user){
for(Integer i:user.getVisitedPlaces()){
if(map.get(i)==null){
map.putIfAbsent(i, 1);
}else{
map.put(i, map.get(i)+1);// lost updates here
}
}
}
protected void compute() {
if(indexfrom==indexto){
computeDirectly(users.get(indexfrom));
}else{
int half=(indexfrom+indexto)/2;
invokeAll(new ForkUsers(users,map,indexfrom,half),new ForkUsers(users,map,half+1,indexto));
}
}
}
即使您使用的是ConcurrentHashMap
,也不会阻止read-update-write争用条件。 两个线程都调用get
,然后都加1,然后都只返回一次更新put
值put
回去。 您可以同步整个读取-更新-写入操作,或者(我的喜好)可以使用AtomicInteger
作为值,而可以使用incrementAndGet
和获取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.