Implementierung variabler Größenarrays der Listenschnittstelle. Alle optionalen Listenvorgänge sind implementiert und alle Elemente einschließlich Null sind zulässig. Neben der Implementierung der Listenschnittstelle bietet diese Klasse auch einige Methoden, um die Größe des Arrays zu manipulieren, mit dem die Liste intern gespeichert wird. (Diese Klasse entspricht ungefähr der Vektorklasse, außer dass diese Klasse nicht synchronisiert ist.) Die Größe, Isempty, Get, Set, Iterator und ListIterator -Vorgänge werden alle zu einem festen Zeitpunkt ausgeführt. Die ADD -Operation wird zu einer gemeinsamen Festzeit ausgeführt, dh das Hinzufügen von N -Elementen dauert O (N). Alle anderen Operationen werden in linearer Zeit (im Allgemeinen) ausgeführt. Diese Implementierung hat einen niedrigeren konstanten Faktor als der für die Implementierung der LinkedList verwendete konstante Faktor. Jede ArrayList -Instanz hat eine Kapazität. Diese Kapazität bezieht sich auf die Größe des Arrays, das zum Speichern von Listenelementen verwendet wird. Es ist immer mindestens der Größe der Liste. Da Elemente ständig zur ArrayList hinzugefügt werden, steigt ihre Kapazität auch automatisch an. Details der Wachstumsstrategie sind nicht angegeben, da es nicht nur so einfach ist wie das Hinzufügen von Elementen, die zu einem festen Zeitaufwand führen. Vor dem Hinzufügen einer großen Anzahl von Elementen kann die Anwendung den Sicherungs -Operationsvorgang verwenden, um die Kapazität der ArrayList -Instanz zu erhöhen. Dies kann die Anzahl der inkrementellen Umverteilungen verringern.
Beachten Sie, dass diese Implementierung nicht synchron ist.
Wenn mehrere Threads gleichzeitig auf eine ArrayList -Instanz zugreifen und mindestens einer der Threads die Liste strukturell ändern, muss sie extern synchronisiert bleiben. (Die strukturelle Modifikation bezieht sich auf einen Betrieb des Hinzufügens oder Entfernens eines oder mehrere Elemente oder die explizit Anpassung der Größe des zugrunde liegenden Arrays. Das Festlegen des Wertes des Elements ist keine strukturelle Modifikation.) Dies wird im Allgemeinen durch Synchronisierungsobjekte durchgeführt, die die Liste auf natürliche Weise zusammenfassen. Wenn ein solches Objekt nicht vorhanden ist, sollte die Liste mithilfe der Methode der Sammlungssynchronisierungsliste "verpackt" werden. Dies geschieht am besten zum Erstellungszeit, um zu verhindern, dass unerwarteter Zugriff auf die Liste synchronisiert wird:
Listlist = collections.synchronizedList (newArrayList (...));
Der von den Iterator- und Listiterator -Methoden dieser Klasse zurückgegebene Iterator scheitern schnell: Nach dem Erstellen des Iterators, es sei denn, die Liste wird strukturell durch die eigene Entfernen oder Hinzufügen des Iterators geändert, wirft der Iterator jederzeit eine ConcurrentModificificationException und jede Möglichkeit, die Liste zu verändern. Daher wird der Iterator angesichts gleichzeitiger Modifikationen bald nicht vollständig scheitern, anstatt ein willkürliches Verhalten zu einem gewissen Zeitpunkt in der Zukunft zu riskieren.
Beachten Sie, dass das schnelle Versagensverhalten des Iterators nicht garantiert werden kann, da es im Allgemeinen unmöglich ist, eine harte Garantie dafür zu erhalten, ob es eine nicht synchrone Änderung gibt. Der schnell fehlerhafte Iterator wird sein Bestes tun, um eine ConcurrentModificationException zu werfen. Daher ist es falsch, ein Programm zu schreiben, das von dieser Ausnahme abhängt, um die Richtigkeit solcher Iteratoren zu verbessern: Das schnelle Verhalten des Iterators sollte nur zum Erkennen von Fehler verwendet werden.
Wie oben gezeigt, erstellen Sie nun eine Listensammlung, ein Thread schreibt die Sammlung und ein Thread löscht die Sammlung
Java.util.ArrayList; import Java.util.Collections; Import Java.util.iterator; Import Java.util.List; import Java.util.random; öffentliche Klasse MyArrayList {/*** Erstellen Sie eine Liste, ein Thread schreibt und ein Thread liest die Iterator- und Listiter -Methoden. Der von der Methode zurückgegebene Iterator ist schnell. DeleteListThread(syncNums).start();}public static void main(String[] args) {new MyArrayList().readWrite();}}class WriteListThread extends Thread {private List<Integer> nums;public WriteListThread(List<Integer> nums) {super("WriteListThread"); this.nums = nums;} // Wege Element 1 public void run () {while (true) {nums.add (new random (). NextInt (1000)); System.out.println (Thread.CurrentThread (). getName ()); nums) {super ("Deletelistthread"); this.nums = nums;} // Löschen Sie das erste Element public void run () {while (true) {try {system.out.println (Thread.CurrentThread (). GetName ()+":"+nums.remove (0);Die Atomoperationen können mit der Liste <Gearneger> syncnums = collections.synchronizedList (NUMS) synchronisiert werden. Aber warum müssen Sie durch das offizielle API -Beispiel manuell Synchronisation hinzufügen?
Listlist = collections.synchronizedList (new ArrayList ()); synchronisiert (Liste) {iterator i = list.Iterator (); // muss im synchronisierten Block sein, während (i.hasnext ()) foo (i.Next ()); }Sehen Sie sich den Quellcode der Sammlungen an. SynchronizedList
SynchronizedCollection (Sammlung <E> c) {if (c == null) werfen neue nullpointerexception (); this.c = c; mutex = this; } Java.util.ArrayList; import Java.util.Collections; Import Java.util.iterator; Import Java.util.List; import Java.util.random; öffentliche Klasse MyArrayList {/*** Erstellen Sie eine Liste, ein Thread schreibt und ein Thread liest die Iterator- und Listiter -Methoden. Der von der Methode zurückgegebene Iterator ist schnell. DeleteListThread(syncNums).start();}public static void main(String[] args) {new MyArrayList().readWrite();}}class WriteListThread extends Thread {private List<Integer> nums;public WriteListThread(List<Integer> nums) {super("WriteListThread"); this.nums = nums;} // Wege Element 1 public void run () {while (true) {nums.add (new random (). NextInt (1000)); System.out.println (Thread.CurrentThread (). getName ()); nums) {super ("Deletelistthread"); this.nums = nums;} // Löschen Sie das erste Element public void run () {while (true) {try {system.out.println (Thread.CurrentThread (). GetName ()+":"+nums.remove (0);Es ist ersichtlich, dass Benutzer für die Sammlungssynchronisationsoperationen unter Verwendung der Sammlungsklasse der Synchronisation Wrapper-Tools manuell nichtatomarische Operationen synchronisieren müssen.
Fügen Sie wie unten einen Thread hinzu, um die Sammlung zu lesen
Klasse ReadListThread erweitert Thread {private Liste <Gefeger> nums; public readListThread (Liste <Integer> nums) {super ("ReadListThread"); this.nums = nums;} // Lesen Sie weiter von Elementen und nichtatomischen Operationen, Sie müssen manuell einen Lock-Public-Void-Lauf hinzufügen () () (wahr) {wahr). {Thread.sleep (1000);} catch (interruptedException e1) {e1.printstacktrace ();} synchronized (nums) {if (nums.size ()> 100) {iterator <integer> iter = nums.Inator (); + ”:” + Iter.next ()) ;;}} else {try {nums.wait (1000);} catch (interruptedException e) {e.printstacktrace ();}}}}}}}}Zusammenfassen
Das obige ist die detaillierte Erklärung des Thread -Synchronisationscode dieses Artikels über das Java -Sammlungs -Framework, und ich hoffe, dass es für alle hilfreich sein wird. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!