
– Szia Amigo!
– Szia, Kim!
– Ma a párhuzamosságról fogok mesélni.
" A Concurrency egy Java osztálykönyvtár, amely speciális osztályokat tartalmaz, amelyeket több szálból történő munkára optimalizáltak. Ez egy nagyon érdekes és kiterjedt téma. De ma csak egy bevezetést fogunk kapni. A csomag neve java.util. párhuzamos csomag. Mesélek néhány érdekes óráról."
" Atomtípusok. "
"Már tudod, hogy még a count++ sem szálbiztos művelet. Ha egy változót 1-gyel növelünk, akkor valójában három művelet történik. Ennek eredményeként a változó megváltoztatásakor ütközés léphet fel."
– Igen, Ellie azt mondta nem régen:
1. szál | 2. szál | Eredmény |
---|---|---|
|
|
|
"Pontosan. Aztán a Java adattípusokat adott hozzá, hogy ezeket a műveleteket egyben, azaz atomosan (az atom oszthatatlan) hajtsa végre."
"Például a Java rendelkezik AtomicInteger, AtomicBoolean, AtomicDouble stb.
"Tegyük fel, hogy létre kell hoznunk egy "számláló" osztályt:
class Counter
{
private int c = 0;
public void increment()
{
c++;
}
public void decrement()
{
c--;
}
public int value()
{
return c;
}
}
– Hogyan tenné szálbiztossá az ebbe az osztályba tartozó objektumokat?
"Nos, az összes metódust szinkronizálnám, és készen is vagyok vele:"
class synchronized Counter
{
private int c = 0;
public synchronized void increment()
{
c++;
}
public synchronized void decrement()
{
c--;
}
public synchronized int value()
{
return c;
}
}
"Jó munka. De hogyan nézne ki, ha atomtípusokat használnánk:"
class AtomicCounter
{
private AtomicInteger c = new AtomicInteger(0);
public void increment()
{
c.incrementAndGet();
}
public void decrement()
{
c.decrementAndGet();
}
public int value()
{
return c.get();
}
}
"A te osztályod és az én osztályom is ugyanúgy működik, de az AtomicIntegerrel rendelkező osztály gyorsabban működik."
– Nos, ez kicsi különbség?
"Igen. Tapasztalataim alapján mindig azt javaslom, hogy szinkronizálja a vezetést. Csak akkor kezdje el átírni a kódot, hogy az atomi típusokat használja tudni, hogy léteznek ilyen típusok. Még ha nem is használja őket aktívan, mindig fennáll az esélye, hogy kódba ütközik, ahol használják őket."
– Egyetértek. Ennek van értelme.
"Mellesleg, észrevette, hogy az atomtípusok nem változtathatók ? A standard Integer osztállyal ellentétben az AtomicInteger tartalmaz módszereket a belső állapot megváltoztatására."
"Értem. Csakúgy, mint a String és a StringBuffer ."
– Igen, valami ilyesmi.
" Szálbiztos gyűjtemények. "
"Egy ilyen gyűjtemény példájaként bemutathatom a ConcurrentHashMap-et. Hogyan tennéd a HashMapot szálbiztossá?"
"Minden metódusát szinkronizálja?"
"Persze, de most képzeld el, hogy van egy ilyen SynchronizedHashMap-ed, és több tucat szál éri el. És másodpercenként százszor új bejegyzés kerül a térképre, és közben az egész objektumot zárolják az olvasáshoz és az íráshoz."
"Nos, ez a szokásos megközelítés. Mit tehetsz?"
– A Java készítői kitaláltak néhány klassz dolgot.
"Először is egyetlen blokkban tárolják az adatokat egy ConcurrentHashMap-ben, de azokat "vödör"-nek nevezett részekre osztják fel. És ha valaki megváltoztatja az adatokat egy ConcurrentHashMap-ben, akkor csak az elért tárolót zároljuk, nem pedig a teljes objektumot. szó szerint sok szál képes egyszerre megváltoztatni az objektumot."
"Másodszor, emlékszel arra, hogy a lista/térkép elemei között nem lehet egyszerre átmásolni és a listát módosítani? Az ilyen kód kivételt dob:"
HashMap<String, Integer> map = new HashMap<String, Integer>();
for (String key: map.keySet())
{
if (map.get(key) == 0)
map.remove(key);
}
"De a ConcurrentHashMapben a következőket teheti:"
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
for (String key: map.keySet())
{
if (map.get(key) == 0)
map.remove(key);
}
"A párhuzamos csomagnak számos előnye van. Csak nagyon jól meg kell értenünk ezeket az osztályokat, hogy használni tudjuk őket."
– Értem. Köszönöm, Kim. Ezek igazán érdekes órák. Remélem, egyszer majd virtuóz módjára elsajátítom őket.
GO TO FULL VERSION