Uvod u sinkronizirane Java zbirke

1. Pregled

Okvir zbirki ključna je komponenta Jave. Pruža širok broj sučelja i implementacija, što nam omogućuje izradu i manipulaciju različitim vrstama kolekcija na jednostavan način.

Iako je upotreba običnih nesinkroniziranih kolekcija u cjelini jednostavna, ona također može postati zastrašujući i sklon pogreškama postupak kada radite u okruženjima s više niti (tj. Istodobno programiranje).

Stoga Java platforma pruža snažnu podršku za ovaj scenarij kroz različitu sinkronizaciju omotači provodi se u okviru Zbirke razred.

Ovi omoti olakšavaju stvaranje sinkroniziranih prikaza isporučenih zbirki pomoću nekoliko statičkih tvorničkih metoda.

U ovom vodiču, duboko ćemo zaroniti u njih omotači statičke sinkronizacije. Također ćemo istaknuti razliku između sinkroniziranih zbirki i istodobnih kolekcija.

2. The synchronizedCollection () Metoda

Prvi omot za sinkronizaciju koji ćemo obraditi u ovom pregledu je synchronizedCollection () metoda. Kao što i samo ime govori, vraća nit sigurnu kolekciju sigurnosno kopiranu navedenom Kolekcija.

Sada, da bismo jasnije razumjeli kako se koristi ova metoda, stvorimo osnovni jedinični test:

Zbirka syncCollection = Collections.synchronizedCollection (novi ArrayList ()); Izvodljivi listOperations = () -> {syncCollection.addAll (Arrays.asList (1, 2, 3, 4, 5, 6)); }; Tema niti1 = nova nit (listOperations); Tema niti2 = nova nit (listOperations); thread1.start (); thread2.start (); nit1.join (); nit2.join (); assertThat (syncCollection.size ()). isEqualTo (12); } 

Kao što je gore prikazano, stvaranje sinkroniziranog prikaza isporučene zbirke ovom metodom vrlo je jednostavno.

Da bismo pokazali da metoda zapravo vraća kolekciju sigurnu za nit, prvo stvorimo nekoliko niti.

Nakon toga ubrizgavamo a Izvodljivo primjer u njihove konstruktore, u obliku lambda izraza. Imajmo to na umu Izvodljivo je funkcionalno sučelje, pa ga možemo zamijeniti lambda izrazom.

Na kraju, samo provjeravamo da svaka nit učinkovito dodaje šest elemenata u sinkroniziranu zbirku, tako da je njezina konačna veličina dvanaest.

3. The synchronizedList () Metoda

Isto tako, slično kao synchronizedCollection () metodu, možemo koristiti synchronizedList () omot za stvaranje sinkroniziranog Popis.

Kao što bismo mogli očekivati, metoda vraća pogled navedenog u nit zaštićen prikaz Popis:

Popis syncList = Collections.synchronizedList (novi ArrayList ());

Nije iznenađujuće da upotreba synchronizedList () metoda izgleda gotovo identično svom kolegi na višoj razini, synchronizedCollection ().

Stoga, kao što smo upravo učinili u prethodnom jediničnom testu, jednom smo stvorili sinkronizaciju Popis, možemo mrijestiti nekoliko niti. Nakon toga učinit ćemo ih za pristup / manipulaciju ciljem Popis na konac siguran način.

Osim toga, ako želimo ponoviti sinkroniziranu zbirku i spriječiti neočekivane rezultate, trebali bismo izričito osigurati vlastitu implementaciju petlje sigurnu za nit. Stoga bismo to mogli postići pomoću a sinkronizirano blok:

Popis syncCollection = Collections.synchronizedList (Arrays.asList ("a", "b", "c")); Popis uppercasedCollection = novi ArrayList (); Izvodljivo listOperations = () -> {sinkronizirano (syncCollection) {syncCollection.forEach ((e) -> {uppercasedCollection.add (e.toUpperCase ());}); }}; 

U svim slučajevima kada trebamo ponoviti sinkroniziranu zbirku, trebali bismo primijeniti ovaj idiom. To je zato što se iteracija sinkronizirane zbirke izvodi kroz višestruke pozive u zbirku. Stoga ih treba izvesti kao jednu atomsku operaciju.

Korištenje sinkronizirano blok osigurava atomskost operacije.

4. The synchronizedMap () Metoda

The Zbirke klasa implementira još jedan uredan omot za sinkronizaciju, nazvan synchronizedMap (). Mogli bismo ga koristiti za jednostavno stvaranje sinkroniziranog Karta.

Metoda vraća prikaz isporučenog prikaza bez niti Karta provedba:

Karta syncMap = Collections.synchronizedMap (nova HashMap ()); 

5. The synchronizedSortedMap () Metoda

Tu je i odgovarajuća implementacija synchronizedMap () metoda. To se zove synchronizedSortedMap (), koji možemo koristiti za stvaranje sinkroniziranog SortedMap primjer:

Karta syncSortedMap = Collections.synchronizedSortedMap (nova TreeMap ()); 

6. The synchronizedSet () Metoda

Dalje, nastavljamo dalje u ovom pregledu, imamo synchronizedSet () metoda. Kao što mu samo ime govori, omogućuje nam stvaranje sinkroniziranih Kompleti uz minimalnu frku.

Omotač vraća kolekciju sigurnu za nit potpomognutu navedenim Postavi:

Postavi syncSet = Collections.synchronizedSet (novi HashSet ()); 

7. The synchronizedSortedSet () Metoda

Konačno, posljednji omot za sinkronizaciju koji ćemo ovdje prikazati je synchronizedSortedSet ().

Slično ostalim implementacijama omota koje smo do sada pregledali, metoda vraća verziju zadane bez niti SortedSet:

SortedSet syncSortedSet = Collections.synchronizedSortedSet (novi TreeSet ()); 

8. Sinkronizirane i istodobne kolekcije

Do ovog trenutka pobliže smo pogledali omote za sinkronizaciju okvira zbirki.

Sad, usredotočimo se na razlike između sinkroniziranih zbirki i istodobnih zbirki, kao što su ConcurrentHashMap i BlockingQueue implementacije.

8.1. Sinkronizirane zbirke

Sinkronizirane kolekcije postižu sigurnost navoja unutarnjim zaključavanjem, a cijele kolekcije su zaključane. Unutarnje zaključavanje provodi se putem sinkroniziranih blokova unutar metoda zamotane zbirke.

Kao što bismo mogli očekivati, sinkronizirane zbirke osiguravaju dosljednost / cjelovitost podataka u okruženjima s više niti. Međutim, mogu doći s kaznom u izvedbi, jer samo jedna pojedinačna nit može istovremeno pristupati zbirci (tzv. Sinkronizirani pristup).

Za detaljan vodič o načinu korištenja sinkronizirano metode i blokove, provjerite naš članak na tu temu.

8.2. Istodobne zbirke

Istodobne zbirke (npr. ConcurrentHashMap), postići sigurnost niti dijeljenjem njihovih podataka u segmente. U ConcurrentHashMap, na primjer, različite niti mogu steći brave na svakom segmentu, tako da više niti može pristupiti Karta istovremeno (također istodobni pristup).

Istodobne zbirke su mnogo učinkovitiji od sinkroniziranih zbirki, zbog svojstvenih prednosti istodobnog pristupa niti.

Dakle, izbor vrste zbirke koja će biti sigurna za nit ovisi o zahtjevima svakog pojedinog slučaja upotrebe i to bi trebalo procijeniti u skladu s tim.

9. Zaključak

U ovom smo članku detaljno pogledali skup omotača za sinkronizaciju implementirane u Zbirke razred.

Uz to, istaknuli smo razlike između sinkroniziranih i istodobnih kolekcija, a također smo pogledali pristupe koje primjenjuju za postizanje sigurnosti niti.

Kao i obično, svi uzorci koda prikazani u ovom članku dostupni su na GitHubu.