devstory

Le Tutoriel de Java CopyOnWriteArrayList

  1. CopyOnWriteArrayList

1. CopyOnWriteArrayList

CopyOnWriteArrayList est une variante thread-safe d'ArrayList. A l'instar d'ArrayList, CopyOnWriteArray gère un tableau pour stocker ses éléments. La différence est que toutes les opérations mutatives telles que add, set, remove, clear, etc... créent une nouvelle copie du tableau qu'elle gère.
public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Observer ce qui se passe au cours de l'ajout d'un élément à CopyOnWriteArrayList:
Le coût d'utilisation de CopyOnWriteArrayList est très élevé, il faut payer plus pour les ressources et les performances. Cependant, CopyOnWriteArrayList est très pratique lorsque vous ne pouvez pas ou ne voulez pas synchroniser en traversant les éléments dans la liste.
Pour mieux comprendre, on prend un exemple où deux Thread(s) utilisent le même objet List. Lorsque Thread-A traverse les éléments de List, il gèle les opérations d'insertion ou de mise à jour sur Listpour l'intégrité de données, mais cela affecte évidemment les opérations de Thread-B.
Lorsque vous créez l'objet Iterator à partir de CopyOnWriteArrayList, cela vous aide à traverser les éléments du tableau actuel (lorsque Iterator est créé). Les éléments de ce tableau ne changent pas durant l'existence d'Iterator. Cela est possible, car toutes les opérations add, set, remove, clear, .. sur CopyOnWriteArrayList créent un autre tableau qui est une copie du tableau actuel.
CopyOnWriteArrayListEx.java
package org.o7planning.copyonwritearraylist.ex;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListEx {

    public static void main(String[] args) {
        // Create a CopyOnWriteArrayList object:
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        Iterator<String> iterator1 = list.iterator();
        
        list.add("X1");
        list.add("X2");
        
        Iterator<String> iterator2 = list.iterator();
        
        System.out.println("--- Iterator 1: -----");
        while(iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }
        
        System.out.println("--- Iterator 2: -----");
        while(iterator2.hasNext()) {
            System.out.println(iterator2.next());
        }
    }
}
Output:
--- Iterator 1: -----
A
B
C
--- Iterator 2: -----
A
B
C
X1
X2
Les opérations de changement d'élément sur les Iterator(add, set, remove) ne sont pas soutenues. Ces méthodes lancent une exception UnsupportedOperationException.
Stream
Les éléments de traversée de CopyOnWriteArrayList via Stream ont les mêmes résultats qu'Iterator.
CopyOnWriteArrayListEx2.java
package org.o7planning.copyonwritearraylist.ex;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;

public class CopyOnWriteArrayListEx2 {

    public static void main(String[] args) {
        // Create a CopyOnWriteArrayList object:
        List<String> list = new CopyOnWriteArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        
        Stream<String> stream1 = list.stream();
        
        list.add("X1");
        list.add("X2");
        
        Stream<String> stream2 = list.stream();
        
        System.out.println("--- Stream 1: -----");
        stream1.forEach(System.out::println);
        
        System.out.println("--- Stream 2: -----");
        stream2.forEach(System.out::println);
    }
}
Output:
--- Stream 1: -----
A
B
C
--- Stream 2: -----
A
B
C
X1
X2
En plus des caractéristiques spéciales mentionnées ci-dessus, CopyOnWriteArrayList est également une List ordinaire, vous pouvez trouver d'autres exemples de List dans l'article ci-dessous: