gpt4 book ai didi

Java fork join并发HashMap解决丢失更新

转载 作者:行者123 更新时间:2023-12-01 14:12:13 25 4
gpt4 key购买 nike

我有一个用户列表,每个用户都有他访问过的一系列地点(例如 list = 1,2,3,1,2,8,10,1...usw.)。现在我想知道每个地方被访问的频率。此外,我真的很想为此进行 fork/join。现在我真正的问题是,你知道这里使用并发HashMap的方法吗,因为当前的问题是丢失了更新

map.put(i, map.get(i)+1);// lost updates here

您是否有一个好主意可以在不锁定整个映射的情况下解决这个问题(是否有像 put() 那样对部分映射进行部分锁定?)。我知道,我可以为每个用户创建一个 map ,然后再次加入他们,但我想,也许有人有更好的解决方案。

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,这也不会阻止读-更新-写竞争条件;两个线程都调用 get,然后都加 1,然后都 put 仅通过一次更新返回值。您可以同步整个读取-更新-写入操作,或者(我的偏好)使用 AtomicInteger 作为值并使用 incrementAndGet 代替。

关于Java fork join并发HashMap解决丢失更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18427970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com