Frage

Ich bin mir nicht sicher, ob dies der richtige Weg, meinen ArrayList zu synchronisieren.

Ich habe eine ArrayList in_queue, die in der registerInQueue Funktion übergeben wird.

ArrayList<Record> in_queue = null;

public void registerInQueue(ArrayList in_queue)
{
    this.in_queue = in_queue;
}

Jetzt versuche ich, es zu synchronisieren. Ist das richtig mein in_queue Objekt sychronizing?

List<Record> in_queue_list = Collections.synchronizedList(in_queue);

synchronized (in_queue_list) {
    while (in_queue_list.size() > 0) {
        in_queue_list.remove(0);
    }
}
War es hilfreich?

Lösung

Sie synchronisieren zweimal, was verlangsamt sinnlos und möglicherweise ist auf den Code: Änderungen während der Iteration über die Liste ein synchronnization über den gesamten Betrieb brauchen, die Sie mit synchronized (in_queue_list) Collections.synchronizedList() in diesem Fall überflüssig werden mit tun werden (es entsteht ein Wrapper, die einzelnen Operationen synchronisiert).

Da jedoch die Liste vollständig entleeren, das iterierten Entfernen des ersten Elements ist der denkbar schlechteste Weg, um es, sice für jedes Element all folgenden Elemente zu tun haben, kopiert werden, so dass diese eine O (n ^ 2) Betrieb -. schrecklich langsam für größere Listen

Stattdessen einfach clear() nennen -. Keine Iteration erforderlich

Edit: Wenn Sie die Single-Methode Synchronisation von Collections.synchronizedList() später brauchen, dann ist dies der richtige Weg:

List<Record> in_queue_list = Collections.synchronizedList(in_queue);
in_queue_list.clear(); // synchronized implicitly, 

Aber in vielen Fällen ist die Single-Methode Synchronisation unzureichend ist (zum Beispiel für alle Iteration, oder wenn Sie einen Wert erhalten, tun Berechnungen basierend auf, und ersetzen Sie es mit dem Ergebnis). In diesem Fall müssen Sie trotzdem manuelle Synchronisation verwenden, so Collections.synchronizedList() ist nur nutzlos zusätzlicher Aufwand.

Andere Tipps

an Ihrem Beispiel Sehen, denke ich, ArrayBlockingQueue (oder seine Geschwister) kann von nutzen sein. Sie kümmern sich um die Synchronisation für Sie, also Fäden in der Warteschlange oder Peek / nehmen, ohne zusätzliche Synchronisation Arbeit an Ihrer Seite schreiben können.

Das ist richtig, und dokumentiert:

http : //java.sun.com/javase/6/docs/api/java/util/Collections.html#synchronizedList (java.util.List)

, aber die Liste zu löschen, rufen Sie einfach List.clear () .

Ja, es ist der richtige Weg, aber der synchronisierten Block erforderlich ist, wenn Sie alle Umzüge wollen zusammen um sicher zu sein - es sei denn, die Warteschlange keine Umzüge erlaubt ist leer. Meine Vermutung ist, dass Sie nur sichere Warteschlange und dequeue Operationen wollen, so können Sie den synchronisierten Block entfernen.

Es gibt jedoch weit fortgeschritten gleichzeitige Warteschlangen in Java wie ConcurrentLinkedQueue

Lassen Sie sich eine normale Liste nehmen (von der Klasse Arraylist implementiert) und macht es synchronisiert. Dies ist in der SynchronizedListExample Klasse gezeigt.     Wir passieren die Collections.synchronizedList Methode eine neue Arraylist von Strings. Die Methode gibt eine synchronisierte Liste der Strings.     // Hier ist SynchronizedArrayList Klasse

package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
* @email kumarmanoj.mtech@gmail.com
* 
*/
public class SynchronizedArrayList {
    static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
    public static void main(String[] args) {    
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<String>());
        synchronizedList.add("Aditya");
        synchronizedList.add("Siddharth");
        synchronizedList.add("Manoj");
        // when iterating over a synchronized list, we need to synchronize access to the synchronized list
        synchronized (synchronizedList) {
            Iterator<String> iterator = synchronizedList.iterator();
            while (iterator.hasNext()) {
                log.info("Synchronized Array List Items: " + iterator.next());
            }
        }    
    }
}

Beachten Sie, dass, wenn sie über die Liste iterieren, dieser Zugang noch einen synchronisierten Block erfolgt über die auf dem synchronizedList Objekt sperrt. In der Regel eine synchronisierte Sammlung iterieren sollte in einem synchronisierten Block durchgeführt werden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top