Probleme mit ConcurrentHashMap und List

ArnoldS

Mitglied
Hallo,
bin schon seit einem ganzen Tag bei einem Race-Condition Problem mit ConcurrentHashMap und List.
Ich starte aus einem Java-Programm mehrere Threads. Alle Threads tragen gemeinsam in einer ConcurrentHashMap ein, hier ein Ausschnitt:
Java:
public class Crawler implements Runnable{
    public static final ConcurrentHashMap<String, List<WordInfo>> indexMap = new ConcurrentHashMap<String, List<WordInfo>>( );
...
Die WordInfo-Klasse beinhaltet Informationen zum Suchergebnis jedes gefundenen Wortes. Ich habe die Methoden von Crawler alle als synchronized deklariert. Aber leider scheint es so, dass der Zugriff auf die List<WordInfo> leider nie synchron erfolgt. dh: Ich habe zwar alle Einträge in der Hash-Tabelle, aber die entsprechende WerteListe ist nach jedem Run verschieden. Vielleicht kann mir ja jemand sagen wie ich auch die Liste synchron halten kann. Ich habe es schon mit Collection.SynchronisedList (oder ähnlich) versucht.
vielen Dank, bin langsam beim Verzweifeln
arnold
 
Guten Morgen,
leider komme ich mit dem Problem nicht so recht weiter. Ich poste hier nun den wichtigsten Teil meines Codes. Vielleicht kann mir ja jemand von euch einen Tipp geben. Hier der Aussschnitt:
Java:
public class Crawler implements Runnable{
    public static final ConcurrentHashMap<String, List<WordInfo>> indexMap = new ConcurrentHashMap<String, List<WordInfo>>( ); //creating the appropriate HashMap
    public  List<WordInfo> currHashValues = (new ArrayList<WordInfo>());
...
 private synchronized void addModifyEntry(String aword){
       currHashValues = (indexMap.get(aword));  //checking if the has-entry already exists
       WordInfo wInfo = new WordInfo(fileName); //creating new WordInfo-Object
            if (currHashValues ==null){ //no Hash-Value
                List<WordInfo> newList = (new ArrayList<WordInfo>()); //creating a new WInfo-Object
                wInfo.increaseCounter(); //increasing the occurance of Object (counter)
                newList.add(wInfo); //adding to the list
                indexMap.put(aword, newList); //put the new List in the Hash-table
                }
            else{ //we have already an entry in the hashtable
                if (currHashValues.contains(wInfo)){  // there exists already a equal entry in the list
                    currHashValues.get(currHashValues.indexOf(wInfo)).increaseCounter(); //therefore we have to modify this entry
                    }
                else {  //there is no such an entry in the list
                    wInfo.increaseCounter(); // we increase the counter
                    currHashValues.add(wInfo); //adding to the list
                    }
                
             }
..
}
Nun, es laufen verschieden Threads dieser Klasse. Alle greifen auf die ein Hashtable zu die aus einem Wert (Wort) und einer Liste der dazugehörigen Dateien gehört.
Habe auch schon versucht bei der Deklaration currHashValues als Collections.SynchronisedList zu deklarieren, aber das verschlechtert nur noch die Sache, das heißt es wird in der Liste immer nur ein Eintrag geführt. Bei meiner Variante funktioniert es eben nicht immer richtig (denke mal Problem race-condition mit meiner Liste). Es werden immer alle Einträge in die Hash-Table gemacht, dh: alle Wörter werden in den Index aufgenommen, nur eben die entsprechende Liste passt nicht immer, vor allem bei sehr vielen und umfangreichen Dokumenten. Vielleicht hat von Euch ja einer einen Tipp, wie ich dieses Problem lösen kann. Mir ist schon klar, dass es sicherlich funktioniert, wenn ich die Crawler-Klasse sequentiell aufrufe.

danke vielmals
arnold
 
Was machen denn jetzt die currHashValues da? ???:L
Code:
 if (currHashValues ==null){ //no Hash-Value [b]Kann doch nie erfüllt sein - die wird ja oben erstellt![/b]
                List<WordInfo> newList = (new ArrayList<WordInfo>()); //creating a new WInfo-Object [b]sollte eine synchronizedList sein[/b]

Insgesamt sieht das jetzt so aus, als hättest du schon lange rumprobiert, um einen Fehler zu beheben... Und die Workarounds, die dort drin zu sein scheinen, um mit dem mutithreading klarzukommen, könnten das ganze langsamer machen, als es mit EINEM Thread wäre. Ggf. schau ich nochmal in die Kristallkugel, und versuch' da was zu basteln, was so ähnlich sein könnte, wie das, was du vorhast...
 

Zurück
Oben