簡體   English   中英

Java fork加入並發HashMap解決丟失的更新

[英]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,然后都只返回一次更新putput回去。 您可以同步整個讀取-更新-寫入操作,或者(我的喜好)可以使用AtomicInteger作為值,而可以使用incrementAndGet和獲取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM