CopyOnWrite-Kokoelma
Olemme tutkineet monia synkronoituja kokoelmia, ja jos olet hallinnut muut, tämä on vieläkin suoraviivaisempi.
Käytännön esimerkki
Verkkosovellus, joka käyttää CopyOnWriteArrayList-kokoelmaa tapahtumatilaajien tallentamiseen. Useat säikeet voivat samanaikaisesti hakea nykyisten tilaajien listan ilmoittaakseen heille muutoksista, kun taas toiset säikeet voivat lisätä tai poistaa tilaajia.
Erot muihin tyyppeihin
CopyOnWrite-kokoelmat luovat kopion kokoelmasta aina, kun siihen tehdään muutos. Tämä varmistaa, että lukuoperaatiot eivät esty tietojen muutosten vuoksi, tarjoten näin säieturvallisuuden lukemiseen, vaikka kirjoitusoperaatiot eivät ole säieturvallisia, koska ne tapahtuvat kokoelman erillisessä kopiossa.
CopyOnWrite-näkymät:
Kuten kuvasta näemme, kun lisätään uusi alkio, tehdään kopio tästä tietorakenteesta. Kaikki säikeet, jotka käyttivät tätä kokoelmaa ennen muutosta, jatkavat toimintaansa ongelmitta, koska nämä muutokset eivät vaikuta heidän käyttämäänsä CopyOnWrite-kopioon!
CopyOnWriteArraySet
CopyOnWriteArraySet on säieturvallinen setin toteutus, joka perustuu CopyOnWriteArrayList-luokkaan. Se varmistaa säieturvallisuuden luomalla uuden kopion pohjasetistä aina, kun tapahtuu muutos, kuten alkion lisääminen tai poistaminen.
Tämä lähestymistapa on erityisen hyödyllinen, kun settiä luetaan usein ja muutetaan harvoin, sillä se tarjoaa kaikille säikeille yhtenäisen näkymän setistä ilman, että tarvitaan synkronointia.
CopyOnWriteArrayList
CopyOnWriteArrayList on säieturvallinen versio ArrayList-luokasta, joka varmistaa säieturvallisuuden luomalla uuden kopion taustalla olevasta taulukosta aina, kun sitä muokataan.
Tämä rakenne tarjoaa vikatolerantin iteraattorin, joka ei heitä ConcurrentModificationException-poikkeusta, koska se toimii tilannekuvalla taulukosta, joka otettiin iteraattorin luontihetkellä. Se soveltuu parhaiten tilanteisiin, joissa lukuoperaatioita tehdään huomattavasti useammin kuin kirjoitusoperaatioita, sillä koko taulukon kopioiminen jokaisen kirjoituksen yhteydessä voi olla raskasta.
Käytännön esimerkki käyttötapauksesta
CopyOnWrite-kokoelman metodit
addIfAbsent(E e): Lisää alkion listaan vain, jos sitä ei ole jo listassa/monikossa.
Main.java
123456789101112131415161718192021package com.example; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); // Attempt to add a duplicate element list.addIfAbsent("apple"); // This will not add "apple" again // Adding a new element list.addIfAbsent("orange"); // This will add "orange" System.out.println(list); // Output: [apple, banana, orange] } }
Tässä esimerkissä "apple" ei lisätä uudelleen, koska se on jo olemassa listassa. addIfAbsent() metodi estää kaksoiskappaleiden lisäämisen ja säilyttää alkioiden yksilöllisyyden.
addAllAbsent(Collection<? extends E> c): Lisää kaikki alkiot annetusta kokoelmasta listaan/monikkoon, ohittaen jo olemassa olevat alkiot.
Main.java
12345678910111213141516171819202122package com.example; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); List<String> newFruits = Arrays.asList("banana", "cherry", "date"); // Adding elements from the collection, ignoring duplicates list.addAllAbsent(newFruits); System.out.println(list); // Output: [apple, banana, cherry, date] } }
Tässä esimerkissä "banana" on jo olemassa listassa, joten addAllAbsent() ei lisää sitä uudelleen. Metodi varmistaa, että vain ainutlaatuiset alkiot annetusta kokoelmasta lisätään listaan.
Kaikki muut CopyOnWrite-kokoelmien metodit ovat samanlaisia kuin niiden yliluokkien metodit; ne vain kopioivat kokoelman tilan aina kun muutoksia tehdään.
Rajoitukset ja Edut
😔Rajoitukset:
CopyOnWrite-kokoelmilla on merkittäviä rajoituksia. Ne aiheuttavat muistikustannuksia, koska kokoelmasta luodaan uusi kopio aina, kun siihen tehdään muutos, mikä voi olla merkittävää. Tämä rakenne tekee niistä vähemmän sopivia tilanteisiin, joissa tarvitaan usein datan muutoksia.
💪Edut:
Toisaalta CopyOnWrite kokoelmat tarjoavat huomattavia etuja. Ne ovat erittäin tehokkaita datan lukemisessa monisäikeisessä ympäristössä. Nämä kokoelmat toimivat poikkeuksellisen hyvin tilanteissa, joissa lukuoperaatioita on huomattavasti enemmän kuin kirjoitusoperaatioita, mikä tekee niistä erinomaisen valinnan tällaisiin käyttötapauksiin.
Kuitenkin, koska kopiointi tapahtuu jokaisen muutoksen yhteydessä, CopyOnWrite-kokoelmat voivat kuluttaa enemmän muistia eivätkä sovellu tilanteisiin, joissa on usein kirjoitusoperaatioita. Ne ovat tehokkaimpia silloin, kun lukuoperaatioita on enemmän kuin kirjoitusoperaatioita.
1. Mitä tapahtuu, kun kutsut addIfAbsent(E e)-metodia CopyOnWriteArrayList-luokassa?
2. Miksi CopyOnWrite-kokoelmat soveltuvat erityisesti tilanteisiin, joissa lukuoperaatioita on paljon ja tietoa muutetaan harvoin?
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme
Awesome!
Completion rate improved to 3.33
CopyOnWrite-Kokoelma
Pyyhkäise näyttääksesi valikon
Olemme tutkineet monia synkronoituja kokoelmia, ja jos olet hallinnut muut, tämä on vieläkin suoraviivaisempi.
Käytännön esimerkki
Verkkosovellus, joka käyttää CopyOnWriteArrayList-kokoelmaa tapahtumatilaajien tallentamiseen. Useat säikeet voivat samanaikaisesti hakea nykyisten tilaajien listan ilmoittaakseen heille muutoksista, kun taas toiset säikeet voivat lisätä tai poistaa tilaajia.
Erot muihin tyyppeihin
CopyOnWrite-kokoelmat luovat kopion kokoelmasta aina, kun siihen tehdään muutos. Tämä varmistaa, että lukuoperaatiot eivät esty tietojen muutosten vuoksi, tarjoten näin säieturvallisuuden lukemiseen, vaikka kirjoitusoperaatiot eivät ole säieturvallisia, koska ne tapahtuvat kokoelman erillisessä kopiossa.
CopyOnWrite-näkymät:
Kuten kuvasta näemme, kun lisätään uusi alkio, tehdään kopio tästä tietorakenteesta. Kaikki säikeet, jotka käyttivät tätä kokoelmaa ennen muutosta, jatkavat toimintaansa ongelmitta, koska nämä muutokset eivät vaikuta heidän käyttämäänsä CopyOnWrite-kopioon!
CopyOnWriteArraySet
CopyOnWriteArraySet on säieturvallinen setin toteutus, joka perustuu CopyOnWriteArrayList-luokkaan. Se varmistaa säieturvallisuuden luomalla uuden kopion pohjasetistä aina, kun tapahtuu muutos, kuten alkion lisääminen tai poistaminen.
Tämä lähestymistapa on erityisen hyödyllinen, kun settiä luetaan usein ja muutetaan harvoin, sillä se tarjoaa kaikille säikeille yhtenäisen näkymän setistä ilman, että tarvitaan synkronointia.
CopyOnWriteArrayList
CopyOnWriteArrayList on säieturvallinen versio ArrayList-luokasta, joka varmistaa säieturvallisuuden luomalla uuden kopion taustalla olevasta taulukosta aina, kun sitä muokataan.
Tämä rakenne tarjoaa vikatolerantin iteraattorin, joka ei heitä ConcurrentModificationException-poikkeusta, koska se toimii tilannekuvalla taulukosta, joka otettiin iteraattorin luontihetkellä. Se soveltuu parhaiten tilanteisiin, joissa lukuoperaatioita tehdään huomattavasti useammin kuin kirjoitusoperaatioita, sillä koko taulukon kopioiminen jokaisen kirjoituksen yhteydessä voi olla raskasta.
Käytännön esimerkki käyttötapauksesta
CopyOnWrite-kokoelman metodit
addIfAbsent(E e): Lisää alkion listaan vain, jos sitä ei ole jo listassa/monikossa.
Main.java
123456789101112131415161718192021package com.example; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); // Attempt to add a duplicate element list.addIfAbsent("apple"); // This will not add "apple" again // Adding a new element list.addIfAbsent("orange"); // This will add "orange" System.out.println(list); // Output: [apple, banana, orange] } }
Tässä esimerkissä "apple" ei lisätä uudelleen, koska se on jo olemassa listassa. addIfAbsent() metodi estää kaksoiskappaleiden lisäämisen ja säilyttää alkioiden yksilöllisyyden.
addAllAbsent(Collection<? extends E> c): Lisää kaikki alkiot annetusta kokoelmasta listaan/monikkoon, ohittaen jo olemassa olevat alkiot.
Main.java
12345678910111213141516171819202122package com.example; import java.util.Arrays; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class Main { public static void main(String[] args) { CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("apple"); list.add("banana"); List<String> newFruits = Arrays.asList("banana", "cherry", "date"); // Adding elements from the collection, ignoring duplicates list.addAllAbsent(newFruits); System.out.println(list); // Output: [apple, banana, cherry, date] } }
Tässä esimerkissä "banana" on jo olemassa listassa, joten addAllAbsent() ei lisää sitä uudelleen. Metodi varmistaa, että vain ainutlaatuiset alkiot annetusta kokoelmasta lisätään listaan.
Kaikki muut CopyOnWrite-kokoelmien metodit ovat samanlaisia kuin niiden yliluokkien metodit; ne vain kopioivat kokoelman tilan aina kun muutoksia tehdään.
Rajoitukset ja Edut
😔Rajoitukset:
CopyOnWrite-kokoelmilla on merkittäviä rajoituksia. Ne aiheuttavat muistikustannuksia, koska kokoelmasta luodaan uusi kopio aina, kun siihen tehdään muutos, mikä voi olla merkittävää. Tämä rakenne tekee niistä vähemmän sopivia tilanteisiin, joissa tarvitaan usein datan muutoksia.
💪Edut:
Toisaalta CopyOnWrite kokoelmat tarjoavat huomattavia etuja. Ne ovat erittäin tehokkaita datan lukemisessa monisäikeisessä ympäristössä. Nämä kokoelmat toimivat poikkeuksellisen hyvin tilanteissa, joissa lukuoperaatioita on huomattavasti enemmän kuin kirjoitusoperaatioita, mikä tekee niistä erinomaisen valinnan tällaisiin käyttötapauksiin.
Kuitenkin, koska kopiointi tapahtuu jokaisen muutoksen yhteydessä, CopyOnWrite-kokoelmat voivat kuluttaa enemmän muistia eivätkä sovellu tilanteisiin, joissa on usein kirjoitusoperaatioita. Ne ovat tehokkaimpia silloin, kun lukuoperaatioita on enemmän kuin kirjoitusoperaatioita.
1. Mitä tapahtuu, kun kutsut addIfAbsent(E e)-metodia CopyOnWriteArrayList-luokassa?
2. Miksi CopyOnWrite-kokoelmat soveltuvat erityisesti tilanteisiin, joissa lukuoperaatioita on paljon ja tietoa muutetaan harvoin?
Kiitos palautteestasi!