Implémentation des tableaux de taille variable de l'interface de liste. Toutes les opérations de liste facultative sont implémentées et tous les éléments, y compris null, sont autorisés. En plus d'implémenter l'interface de liste, cette classe fournit également quelques méthodes pour manipuler la taille du tableau utilisé pour stocker la liste en interne. (Cette classe est à peu près équivalente à la classe vectorielle, sauf que cette classe est hors de synchronisation.) La taille, les opérations de taille, d'isempty, de get, de set, d'itérateur et de listiterator s'exécutent tous à un temps fixe. L'opération ADD fonctionne à un temps fixe partagé, c'est-à-dire, l'ajout de n éléments prend du temps (n). Toutes les autres opérations fonctionnent en temps linéaire (en général). Cette implémentation a un facteur constant inférieur à celui du facteur constant utilisé pour la mise en œuvre de la liste Linked. Chaque instance ArrayList a une capacité. Cette capacité fait référence à la taille du tableau utilisé pour stocker les éléments de la liste. Il est toujours au moins égal à la taille de la liste. Étant donné que les éléments sont constamment ajoutés à l'arraylist, leur capacité augmente également automatiquement. Les détails de la stratégie de croissance ne sont pas spécifiés, car il n'est pas aussi simple que d'ajouter des éléments qui se traduiront par une surcharge de temps fixe. Avant d'ajouter un grand nombre d'éléments, l'application peut utiliser l'opération d'assurécapacité pour augmenter la capacité de l'instance ArrayList. Cela peut réduire le nombre de redistributions incrémentielles.
Notez que cette implémentation n'est pas synchrone.
Si plusieurs threads accèdent à une instance ArrayList en même temps et qu'au moins l'un des threads modifie structurellement la liste, il doit rester synchronisé en externe. (La modification structurelle fait référence à toute opération d'ajout ou de suppression d'un ou plusieurs éléments, ou d'ajuster explicitement la taille du tableau sous-jacent; la définition de la valeur de l'élément n'est pas une modification structurelle.) Cela se fait généralement en synchronisant des objets qui résument naturellement la liste. Si un tel objet n'existe pas, la liste doit être "enveloppée" à l'aide de la méthode CollectionS.SynchronizedList. Cela est mieux fait à l'heure de la création pour empêcher le synchronisé d'accès inattendu à la liste:
ListList = collections.SynchronizedList (newArrayList (...));
L'itérateur renvoyé par les méthodes Iterator et ListIterator de cette classe échoue rapidement: après avoir créé l'itérateur, à moins que la liste ne soit modifiée à partir de la méthode de suppression ou d'ajout de l'itérateur, l'itérateur lancera à tout moment un itérateur concurrentModification, à tout moment et de modifier la liste. Par conséquent, face aux modifications simultanées, l'itérateur échouera bientôt complètement, plutôt que de risquer un comportement incertain arbitraire à un moment incertain à l'avenir.
Notez que le comportement de défaillance rapide de l'itérateur ne peut pas être garanti, car en général, il est impossible de garantir des garanties difficiles pour savoir s'il y a une modification simultanée hors synchrone. L'Itérateur à tails rapides fera de son mieux pour lancer une conception en conception concurrente. Par conséquent, il est faux d'écrire un programme qui dépend de cette exception pour améliorer l'exactitude de ces itérateurs: le comportement de défaillance rapide de l'itérateur ne doit être utilisé que pour détecter les bogues.
Comme indiqué ci-dessus, créez maintenant une collection de liste, un fil écrit la collection et un fil supprime la collection
Importer java.util.arraylist; import java.util.collections; import java.util.iterator; import java.util.list; import java.util.random; public class MyArrayList {/ ** * créer une liste, un thread écrit, et un thread lit les méthodes iTerator and ListIterator. L'itérateur renvoyé par la méthode est rapide. * / Public void readwrite () {list <nteger> nums = new ArrayList <Neger> (); list <Integer> synnums = collections.synchronizeliselist (nums); // démarrer le thread d'écriture new writeListThread (syncnums) .start (); // démarrer le thread Delete New New DeleteListThread (syncnums) .start ();} public static void main (String [] args) {new MyArrayList (). Readwrite ();}} classe WriteListThread étend Thread {private list <nteger> nums; public writeListThread (list <Integer> nums) {super ("writeLeLedThread"); this.nums = nums;} // continuer à écrire l'élément 1 public void run () {while (true) {nums.add (new random (). nextInt (1000)); System.out.println (thread.currentThread (). GetName ());}}} Class DeleteleListthread étend Threger {private list <Integer> nums) {super ("DeleteListThread"); this.nums = nums;} // supprimer le premier élément public void run () {while (true) {try {System.out.println (thread.currentThread ().Les opérations atomiques peuvent être synchronisées par List <Integer> syncnums = collections.SynchronizedList (NUMS); Mais pourquoi avez-vous besoin d'ajouter manuellement la synchronisation par l'exemple API officiel?
List list = collection.SynchronizedList (new ArrayList ()); synchronisé (list) {iterator i = list.iterator (); // doit être dans un bloc synchronisé while (i.hasnext ()) foo (i.next ()); }Afficher le code source des collectes.SynchronizedList
SynchronizedCollection (collection <e> c) {if (c == null) lance un nouveau nullpointerException (); this.c = c; mutex = this; } Importer java.util.arraylist; import java.util.collections; import java.util.iterator; import java.util.list; import java.util.random; public class MyArrayList {/ ** * créer une liste, un thread écrit, et un thread lit les méthodes iTerator and ListIterator. L'itérateur renvoyé par la méthode est rapide. * / Public void readwrite () {list <nteger> nums = new ArrayList <Neger> (); list <Integer> synnums = collections.synchronizeliselist (nums); // démarrer le thread d'écriture new writeListThread (syncnums) .start (); // démarrer le thread Delete New New DeleteListThread (syncnums) .start ();} public static void main (String [] args) {new MyArrayList (). Readwrite ();}} classe WriteListThread étend Thread {private list <nteger> nums; public writeListThread (list <Integer> nums) {super ("writeLeLedThread"); this.nums = nums;} // continuer à écrire l'élément 1 public void run () {while (true) {nums.add (new random (). nextInt (1000)); System.out.println (thread.currentThread (). GetName ());}}} Class DeleteleListthread étend Threger {private list <Integer> nums) {super ("DeleteListThread"); this.nums = nums;} // supprimer le premier élément public void run () {while (true) {try {System.out.println (thread.currentThread ().On peut voir que pour les opérations de synchronisation de collection, en utilisant la classe d'outils de wrapper de synchronisation des collections, les utilisateurs doivent synchroniser manuellement les opérations non atomiques.
Comme indiqué ci-dessous, ajoutez un fil pour lire la collection
class ReadListThread étend Thread {private list <Integer> nums; public readLaidThread (list <Integer> nums) {super ("readLaidThread"); this.nums = nums;} // continuer à lire les éléments et les opérations non atomiques, vous devez ajouter manuellement un verrouillage Void run () {while (true) {// somnolence, gère le verrou {Thread.sleep (1000);} catch (InterruptedException e1) {e1.printStackTrace ();} synchronisé (nums) {if (nums.size ()> 100) {iterator <nteger> iter = nums.iterator (); while (iter.hasnext () {system.out.trultln (thread.curRentShrame ().) GetNe + ":" + Iter.next ()) ;;}} else {try {nums.wait (1000);} catch (interruptedException e) {e.printStackTrace ();}}}}}}}}Résumer
Ce qui précède est toute l'explication détaillée du code de synchronisation des threads de cet article sur le cadre de la collection Java, et j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!