Útmutató a CopyOnWriteArrayList használatához

1. Áttekintés

Ebben a gyors cikkben megnézzük a CopyOnWriteArrayList tól java.util.egyidejű csomag.

Ez egy nagyon hasznos konstrukció a több szálon futó programokban - amikor egy szálon biztonságos módon akarunk iterálni egy listán, szinkronizálás nélkül.

2. CopyOnWriteArrayList API

A CopyOnWriteArrayList érdekes technikát használ szálbiztonságossá szinkronizálás nélkül. Amikor a módosítási módszerek bármelyikét használjuk - például add () vagy eltávolít () - a teljes tartalma CopyOnWriteArrayList az új belső másolatba kerül.

Ezen egyszerű tény miatt biztonságosan tudunk iterálni a listán, még akkor is, ha ezzel párhuzamos módosítás történik.

Amikor felhívjuk a iterátor () módszer a CopyOnWriteArrayList, visszakapunk egy Iterátor a tartalom megváltoztathatatlan pillanatképével alátámasztva CopyOnWriteArrayList.

Tartalma az adatok pontos másolata, amely a Tömb lista attól kezdve, amikor a Iterátor elkészült. Még ha időközben más szál is hozzáad vagy eltávolít egy elemet a listából, ez a módosítás új másolatot készít azokról az adatokról, amelyeket a lista további adatkeresése során felhasználnak.

Ennek az adatstruktúrának a jellemzői teszik különösen hasznosá azokban az esetekben, amikor gyakrabban ismételgetünk rajta, mint módosítunk. Ha az elemek hozzáadása a forgatókönyvünkben gyakori művelet, akkor CopyOnWriteArrayList nem lesz jó választás - mert a további példányok mindenképpen alacsonyabb teljesítményhez vezetnek.

3. Iterating Over CopyOnWriteArrayList Beszúrás közben

Tegyük fel, hogy létrehozzuk a CopyOnWriteArrayList amely egész számokat tárol:

CopyOnWriteArrayList számok = új CopyOnWriteArrayList (új egész szám [] {1, 3, 5, 8});

Ezután azt a tömböt szeretnénk iterálni, ezért létrehozunk egy Iterátor példa:

Iterátor iterátor = számok.iterátor ();

Azután Iterátor létrejön, új elemet adunk a számok lista:

számok.add (10);

Ne feledje, hogy amikor iterátort hozunk létre a CopyOnWriteArrayList, megváltoztathatatlan pillanatfelvételt kapunk az akkori listában szereplő adatokról iterátor () felhívták.

Emiatt, miközben iterálunk rajta, nem látjuk a számot 10 az iterációban:

Lista eredménye = new LinkedList (); iterator.forEachRemaining (eredmény :: hozzáadás); assertThat (eredmény) .Csak (1, 3, 5, 8) tartalmaz;

Utólagos ismétlés az újonnan létrehozott használatával Iterátor a hozzáadott 10-es számot is visszaadja:

Iterátor iterátor2 = számok.iterátor (); Lista eredménye2 = új LinkedList (); iterator2.forEachRemaining (eredmény2 :: hozzáadás); assertThat (eredmény2) .Csak (1, 3, 5, 8, 10) tartalmaz;

4. Az iterálás közbeni eltávolítás nem megengedett

A CopyOnWriteArrayList azért jött létre, hogy lehetővé tegye az elemek biztonságos ismétlésének lehetőségét akkor is, ha az alapul szolgáló lista módosul.

A másolási mechanizmus miatt a eltávolítás () művelet a visszaküldött Iterátor nem megengedett - ennek eredményeként UnsupportedOperationException:

@Test (várható = UnsupportedOperationException.class) public void whenIterateOverItAndTryToRemoveElement_thenShouldThrowException () {CopyOnWriteArrayList number = new CopyOnWriteArrayList (new Integer [] 8, 3; Iterátor iterátor = számok.iterátor (); while (iterator.hasNext ()) {iterator.remove (); }}

5. Következtetés

Ebben a gyors bemutatóban megnéztük a CopyOnWriteArrayList végrehajtás a java.util.egyidejű csomag.

Láttuk ennek a listának az érdekes szemantikáját és azt, hogy miként lehet szálbiztos módon iterálni, míg más szálak folytathatják az elemek beszúrását vagy eltávolítását belőle.

Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.