"Helló, Amigo! Van egy csodaszerünk – minden betegségre gyógyír. Mint már láttuk, az ellenőrizetlen szálváltás problémát jelent."
"Miért nem tudják maguk a szálak eldönteni, hogy mikor váltsanak a következő szálra? Tegyenek meg mindent, amit meg kell tenniük, majd jelezzék: «Kész vagyok!»?
"Még nagyobb probléma lenne, ha a szálak maguk irányítsák a váltást. Tegyük fel, hogy valami rosszul megírt kódja van, és a szál soha nem adja fel a CPU-t. Régen ez így működött. És elég rémálom volt."
"Rendben. Szóval mi a megoldás?"
" Más szálak blokkolása. Ez így működik."
Világossá vált, hogy a szálak zavarják egymást, amikor megosztott objektumokat és/vagy erőforrásokat próbálnak használni . Ahogy a példában is láttuk a konzol kimeneténél: van egy konzol, és az összes szál arra kerül. Ez rendetlen.
Feltaláltak tehát egy különleges tárgyat: a mutexet . Olyan ez, mint egy tábla a fürdőszobaajtón, amelyen az áll, hogy «rendelkezésre áll / foglalt» . Két állapota van: az objektum elérhető vagy foglalt . Ezeket az állapotokat „zártnak” és „feloldottnak” is nevezik.
Ha egy szálnak más szálakkal megosztott objektumra van szüksége, akkor ellenőrzi az objektumhoz társított mutexet. Ha a mutex fel van oldva, akkor a szál zárolja ("foglaltnak" jelöli), és elkezdi használni a megosztott erőforrást. Miután a szál elvégezte a dolgát, a mutex feloldódik ("elérhető"-ként van megjelölve).
Ha a szál használni akarja az objektumot, és a mutex zárolva van, akkor a szál elalszik, amíg vár. Amikor a mutexet a megszálló szál végre feloldja, a mi szálunk azonnal lezárja és futni kezd. Tökéletes a hasonlat a fürdőszobaajtó táblájával.
"Szóval hogyan dolgozzak egy mutex-szel? Kell-e speciális objektumokat létrehoznom?"
"Ennél sokkal egyszerűbb. A Java készítői beépítették ezt a mutexet az Object osztályba. Így nem is kell létrehoznia. Minden objektum része. Így működik az egész:"
Kód | Leírás |
---|---|
|
A swap metódus felcseréli a név1 és név2 változók értékeit.
Mi történhet, ha egyszerre két szálból hívják? |
Tényleges kódvégrehajtás | Az első szál kódja | A második szál kódja |
---|---|---|
|
|
|
Alsó vonal |
---|
A változók értékeit kétszer felcseréltük, visszaállva az eredeti helyükre. |
Ügyeljen a szinkronizált kulcsszóra .
– Igen, mit jelent?
"Amikor egy szál belép egy szinkronizáltként megjelölt kódblokkba, a Java gép azonnal zárolja a szinkronizált szó után zárójelben jelzett objektum mutexét. Más szál nem léphet be ebbe a blokkba, amíg a mi szálunk ki nem hagyja. Amint a szálunk elhagyja a szinkronizált blokk esetén a mutex azonnal és automatikusan feloldódik, és elérhető lesz egy másik szál számára."
Ha a mutex foglalt, akkor a szálunk megáll, és várja, hogy felszabaduljon.
"Olyan egyszerű és olyan elegáns. Ez egy gyönyörű megoldás."
– Igen. De szerinted mi fog történni ebben az esetben?
Kód | Leírás |
---|---|
|
A swap és a swap2 metódusok ugyanazon a mutexen ( ez az objektum) osztoznak. |
Mi történik, ha az egyik szál a swap metódust, a másik pedig a swap2 metódust?
"Mivel a mutex ugyanaz, a második szálnak meg kell várnia, amíg az első szál elhagyja a szinkronizált blokkot. Így nem lesz probléma az egyidejű hozzáféréssel."
"Jól van, Amigo! Ez a helyes válasz!"
Most szeretném felhívni a figyelmet arra, hogy a szinkronizálással nem csak kódblokkok, hanem metódusok is megjelölhetők. Ez a következőket jelenti:
Kód | Mi történik valójában |
---|---|
|
|
GO TO FULL VERSION