example - java multithreading methods



Java Synchronisierte Liste (5)

Aus Collections#synchronizedList(List) javadoc

Gibt eine synchronisierte (threadsichere) Liste zurück, die von der angegebenen Liste unterstützt wird. Um den seriellen Zugriff zu gewährleisten, ist es von entscheidender Bedeutung, dass der Zugriff auf die Sicherungsliste über die zurückgegebene Liste erfolgt. Es ist zwingend erforderlich, dass der Benutzer bei der Iteration die zurückgegebene Liste manuell synchronisiert. Die Nichtbefolgung dieses Hinweises kann zu nicht-deterministischem Verhalten führen.

https://ffff65535.com

Ich habe eine vorbelegte Array-Liste. Und ich habe mehrere Threads, die Elemente aus der Array-Liste entfernen werden. Jeder Thread ruft die Methode remove auf und entfernt ein Element aus der Liste. Verschafft mir der folgende Code ein konsistentes Verhalten?

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

void remove(String item)
{
     do something; (doesn't work on the list)
     list.remove(item);
}

Vielen Dank!


Das sollte in Ordnung sein, solange Sie nicht die Methode "remove" benötigen, um atomar zu sein.

Mit anderen Worten, wenn das "etwas tun" überprüft, dass das Element zum Beispiel mehr als einmal in der Liste erscheint, ist es möglich, dass das Ergebnis dieser Überprüfung falsch ist, wenn Sie die nächste Zeile erreichen.

Stellen Sie außerdem sicher, dass Sie beim Iterieren in der Liste synchronisieren:

synchronized(list) {
    for (Object o : list) {}
}

Wie von Peter Lawrey erwähnt, kann CopyOnWriteArrayList Ihnen das Leben erleichtern und eine bessere Leistung in einer hochgradig parallelen Umgebung bieten.


Ja, es wird gut funktionieren, wenn Sie die Liste synchronized haben. Ich würde vorschlagen, dass Sie CopyOnWriteArrayList .

CopyOnWriteArrayList<String> cpList=new CopyOnWriteArrayList<String>(new ArrayList<String>());

    void remove(String item)
    {
         do something; (doesn't work on the list)
                 cpList..remove(item);
    }

Ja, seien Sie vorsichtig, wenn Sie auch über die Liste iterieren, denn in diesem Fall müssen Sie darauf synchronisieren. Aus dem Javadoc :

Es ist zwingend erforderlich, dass der Benutzer bei der Iteration manuell die zurückgegebene Liste synchronisiert:

List list = Collections.synchronizedList(new ArrayList());
    ...
synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}

Oder Sie können CopyOnWriteArrayList das für Schreibvorgänge langsamer ist, aber dieses Problem nicht aufweist.


synchronized(list) {
    for (Object o : list) {}
}




multithreading