Ú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.