2017-02-20 4 views
0

Ich habe eine ListeIst es sicher, dieselbe Liste gleichzeitig zu durchlaufen?

testList= new ArrayList<String>(); // gets initialized once at the very beginning init(). This list never changes. It's static and final. 

ich eine statische Methode, die, wenn ein Eingabewert überprüft in dieser Liste ist:

public static boolean isInList (String var1) 
      throws InterruptedException { 

     boolean in = false; 

     for (String s : testList) { 

      if (s.equals(var1)) 
      { 
       in = true; 
       break; 
      } 
     } 

     return in; 
    } 

Ich habe eine Menge von Threads, die diese Methode gleichzeitig verwenden und überprüfen, ob Ein bestimmter Wert ist in dieser Liste. Es scheint gut zu funktionieren. Ich bin mir jedoch nicht sicher, ob das sicher ist. Mache ich das richtig? Ist es threadsicher?

+0

Ja, es ist, es sei denn Sie hinzufügen/löschen/Elemente auf die Aktualisierung Liste. Verwenden Sie für solche Abfragen übrigens eine andere Datenstruktur. Zum Beispiel eine hashmap – raven

+3

Warum benutzen Sie nicht 'testList.contains (var1)'? – RealSkeptic

Antwort

0

Wie lange verwenden können, wie Sie, dass niemand auf der Liste garantieren kann, ist das Schreiben, dann ist es sicher.

Beachten Sie, dass auch wenn die Liste ist static und final, der Code selbst garantiert nicht, dass die Liste nicht verändert wird. Ich empfehle stattdessen, stattdessen Collections.unmodifiableList() zu verwenden, da garantiert wird, dass der Liste kein Element hinzugefügt oder aus der Liste entfernt wird.


By the way, können Sie Ihren Code auf diese umschreiben:

public static boolean isInList(String var1) { 
    for (String s : testList) { 
     if (Objects.equals(s, var1)) { 
      return true; 
     } 
    } 
    return false; 
} 

oder nur

testList.contains(var1); 
3

Es ist Thread-sicher, solange kein Thread die Liste ändert, während andere Threads es lesen.

Wenn Sie Iteratoren über die Liste verwenden, werden sie "fail-fast" (wie in throw ConcurrentModificationException), wenn die Liste unter ihnen geändert wird. Andere Methoden des Zugriffs (d. H. get(n)) werden keine Ausnahme auslösen, können jedoch unerwartete Ergebnisse liefern.

Dies ist alles sehr detailliert im Javadoc für List und ArrayList, die Sie sorgfältig studieren sollten.

+0

Und, um nur zu bemerken, die Liste muss in jedem Thread an erster Stelle sicher veröffentlicht worden sein. * Die meisten Methoden zur Behandlung von Referenzen auf Threads sind in Ordnung; einfach nicht in einem nichtflüchtigen statischen Feld speichern und die Threads daraus lesen lassen. Beachten Sie auch, dass Sie sich bei einer Liste ohne Threadsafe (wie ArrayList) nicht auf das Verhalten von ConcurrentModificationException verlassen können, da die Werte, auf die es für die Überprüfung angewiesen ist, anfällig für Race-Bedingungen sind. – yshavit

+0

Die Iterator-Methode der Liste (die in Ihrer for-Schleife aufgerufen wird) gibt bei jedem Aufruf eine neue Instanz des Iterators zurück, sodass Sie die Liste ohne Probleme mehrmals durchlaufen können – Bruno

2

ArrayList ist kein Thread-sicheres Objekt. Es mag jetzt für Sie funktionieren, aber im Allgemeinen sollten Sie bei der Arbeit mit Threads sicherstellen, dass Sie thread-sichere Objekte verwenden, die erwartungsgemäß mit Ihren Threads arbeiten.

Sie Collections.synchronizedList()

testList = Collections.synchronizedList(new ArrayList<String>());

Verwandte Themen