简体   繁体   中英

Java fork join concurrent HashMap solve lost updates

I have a list of users and each user has a sequence of places he has visited (eg list = 1,2,3,1,2,8,10,1...usw.). Now I want figure out how often each place has been visited. Futhermore, I really want to take fork/join for that. Now my acutal question is, do you know a way to use the concurrentHashMap here, because the current problem is that there are lost updates at

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

Do you have a nice idea to solve that without locking the whole map (is there are partial lock for parts of the map as it is for put()?). I know, I could create a map for each user then join them again, but I thought, perhaps someone has a better solution.

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

    }
}

Even though you're using a ConcurrentHashMap , that doesn't prevent read-update-write race conditions; both threads call get , then both add 1, then both put the value with just the single update back. You can either synchronize the whole read-update-write operation or (my preference) use an AtomicInteger for the value and use incrementAndGet instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM