2013-02-05 7 views
5

Ich habe eine Liste von string (tagList), die unter mehreren Threads zum Lesen geteilt werden müssen, also erstelle ich eine unmodifizierbare Version davon und übergebe sie an Threads, ich bin nicht sicher, ob es threadsicher ist, da Threads diese Liste nur so lesen Ich denke, es sollte in Ordnung sein?ist nicht änderbar Thread sicher?

auch wenn ich diese unmodifialble Liste zu den Threads überließe, übergibt es eine einzelne Kopie und von Threads geteilt oder erstellt es mehrere Kopien und übergibt eine Kopie an jeden Thread?

hier ist mein Code:

final List<String> tList = Collections.unmodifiableList(tagList); 
List<Future<Void>> calls = new ArrayList<Future<Void>>(); 

FileStatus[] fsta = _fileSystem.listStatus(p);  
for (FileStatus sta : fsta) { 
    final Path path = new Path(sta.getPath(), "data.txt"); 
    if (!_fileSystem.exists(path)) {   
     continue; 
    } 
    else { 
     calls.add(_exec.submit(new Callable<Void>() { 
      @Override 
      public Void call() throws Exception { 
       filterData(path, tList); 
       return null; 
      } 
     })); 
    } 
} 
+1

Es ist fadensicher. – jdb

Antwort

6

Dies hängt vollständig davon ab, ob die zugrunde liegende Liste bei Lesevorgängen Thread-sicher ist. Die nicht änderbare Liste übergibt alle gelesenen Aufrufe wie size(), get (int) usw. einfach an die darunterliegende Liste ohne zusätzliche Synchronisation.

Stellen Sie sich zum Beispiel vor, Implementierung von List, die Hash-Code zwischenspeichert, anstatt es jedes Mal zu berechnen, wenn es benötigt wird. Für eine solche Implementierung ist die Methode hashCode() tatsächlich nicht schreibgeschützt, da sie den intern zwischengespeicherten Hashcodewert ändern kann. Ein anderes Beispiel ist eine Variante von LinkedList, die den Verweis auf den zuletzt aufgerufenen Eintrag zusammen mit seinem Index zwischenspeichert, so dass weitere Versuche, auf in der Nähe befindliche Elemente zuzugreifen, viel schneller ausgeführt werden. Für eine solche Implementierung ist die Methode get (int) nicht schreibgeschützt, da sie den zwischengespeicherten Verweis und Index aktualisiert und somit wahrscheinlich nicht Thread-sicher ist.

+1

Und die zugrunde liegende 'Liste' kann modifiziert werden. Auch vermutlich unsicher, wenn sie unsicher veröffentlicht werden. –

+0

Die Tatsache, dass die zugrunde liegende Liste geändert werden kann, hat nichts mit Thread-Sicherheit zu tun. –

+3

Ich folge nicht. Wenn die zugrunde liegende 'List' in einem anderen Thread als der' unmodifiedList' geändert wird, wird das Multithread-Zugriff sein, selbst wenn die Leseoperation auf der zugrunde liegenden 'List' keine interne Änderung verursacht. –

2

Es ist Thread-sicher (da es nicht geändert werden kann). Es passiert die gleiche Kopie herum.

Allerdings ist die verpackte Liste (tagList) immer noch NICHT Thread-sicher. Sie dürfen die umschlossene Liste nicht ändern, während sie freigegeben wird. Der einzige Grund, warum die von unmodifiableList() zurückgegebene Liste sicher ist, liegt darin, dass Änderungen an der umschlossenen Liste nicht zulässig sind.

0

Wie Sie sagen, dass die Liste unmodifialble ist; daher wird es threadsicher sein.

Wenn Sie ein Objekt übergeben, übergeben Sie den Verweis auf das Objekt (und nicht das tatsächliche Objekt). Da es eine einzelne Kopie gibt und diese nicht verändert wird, bleibt sie threadsicher.

Nur eine Warnung; Greifen Sie niemals direkt auf tagList zu. Greifen Sie auf sie immer durch umschlossene unmodifizierbare Sammlung mit dem Namen tList zu. Dies kann erreicht werden, wenn Sie es richtig einkapseln.