Gids voor CopyOnWriteArrayList

1. Overzicht

In dit korte artikel zullen we kijken naar de CopyOnWriteArrayList van de java.util.concurrent pakket.

Dit is een zeer nuttige constructie in de multi-threaded programma's - wanneer we een lijst op een threadveilige manier willen herhalen zonder een expliciete synchronisatie.

2. CopyOnWriteArrayList API

Het ontwerp van de CopyOnWriteArrayList gebruikt een interessante techniek om het thread-safe te maken zonder dat synchronisatie nodig is. Wanneer we een van de wijzigingsmethoden gebruiken, zoals toevoegen() of verwijderen () - de hele inhoud van het CopyOnWriteArrayList wordt gekopieerd naar de nieuwe interne kopie.

Vanwege dit simpele feit, we kunnen de lijst op een veilige manier herhalen, zelfs als er gelijktijdige wijziging plaatsvindt.

Als we de iterator () methode op de CopyOnWriteArrayList, we krijgen een terug Iterator ondersteund door de onveranderlijke momentopname van de inhoud van het CopyOnWriteArrayList.

De inhoud is een exacte kopie van de gegevens die zich in een ArrayList vanaf het moment dat de Iterator werd opgericht. Zelfs als in de tussentijd een andere thread een element toevoegt aan of verwijdert uit de lijst, is die wijziging het maken van een nieuwe kopie van de gegevens die zullen worden gebruikt bij elke verdere opzoeking van gegevens uit die lijst.

De kenmerken van deze datastructuur maken het vooral handig in gevallen waarin we er vaker overheen gaan dan dat we het aanpassen. Als het toevoegen van elementen een veel voorkomende bewerking is in ons scenario, dan CopyOnWriteArrayList zal geen goede keuze zijn - omdat de extra exemplaren zeker tot ondermaatse prestaties zullen leiden.

3. Itereren CopyOnWriteArrayList Tijdens het invoegen

Laten we zeggen dat we een instantie maken van het CopyOnWriteArrayList die gehele getallen opslaat:

CopyOnWriteArrayList-nummers = nieuwe CopyOnWriteArrayList (nieuw geheel getal [] {1, 3, 5, 8});

Vervolgens willen we die array herhalen, dus maken we een Iterator voorbeeld:

Iterator iterator = numbers.iterator ();

Na de Iterator is gemaakt, voegen we een nieuw element toe aan de nummers lijst:

numbers.add (10);

Houd er rekening mee dat wanneer we een iterator maken voor de CopyOnWriteArrayList, we krijgen een onveranderlijke momentopname van de gegevens in de lijst op dat moment iterator () heette.

Daarom zullen we, terwijl we erover nadenken, het nummer niet zien 10 in de iteratie:

Lijstresultaat = nieuwe LinkedList (); iterator.forEachRemaining (resultaat :: toevoegen); assertThat (resultaat) .containsOnly (1, 3, 5, 8);

Volgende iteratie met behulp van nieuw gemaakt Iterator retourneert ook het getal 10 dat is toegevoegd:

Iterator iterator2 = numbers.iterator (); Lijst resultaat2 = nieuwe LinkedList (); iterator2.forEachRemaining (result2 :: add); assertThat (resultaat2) .containsOnly (1, 3, 5, 8, 10);

4. Verwijderen tijdens het herhalen is niet toegestaan

De CopyOnWriteArrayList is gemaakt om de mogelijkheid te bieden om veilig over elementen te herhalen, zelfs wanneer de onderliggende lijst wordt gewijzigd.

Vanwege het kopieermechanisme is de verwijderen() operatie op de geretourneerde Iterator is niet toegestaan ​​- resulterend met UnsupportedOperationException:

@Test (verwacht = UnsupportedOperationException.class) public void whenIterateOverItAndTryToRemoveElement_thenShouldThrowException () {CopyOnWriteArrayList-nummers = nieuwe CopyOnWriteArrayList (nieuw geheel getal [] {1, 3, 5, 8}); Iterator iterator = numbers.iterator (); while (iterator.hasNext ()) {iterator.remove (); }}

5. Conclusie

In deze korte tutorial hebben we de CopyOnWriteArrayList implementatie van de java.util.concurrent pakket.

We hebben de interessante semantiek van deze lijst gezien en hoe deze op een threadveilige manier kan worden herhaald, terwijl andere threads er elementen uit kunnen blijven invoegen of verwijderen.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in het GitHub-project - dit is een Maven-project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.