Szálak szinkronizálása

Szálak szinkronizálása

A többszálú működési mód új lehetőségeket nyit meg a programozók számára, de ezekhez a lehetőségekhez képest meg kell fizetnie az alkalmazás és a hibakeresés folyamatának bonyolultságát. A legfontosabb nehézség, amelyet a programozók, akik soha nem hoztak létre többszálú alkalmazásokban, az egymásnak megfelelő szálak szinkronizálása.

Mire és mikor van rá szükség?

Egyetlen menetes program, például az MS-DOS program, a számítógép összes erőforrását kizárólagos rendelkezésére bocsátja. Mivel csak egy folyamat van egy egyszálú rendszerben, ezeket a forrásokat a program logikájához tartozó sorrendben használja. A többszálas rendszerben párhuzamosan futó folyamatok és szálak ugyanabban az erőforrásban próbálnak ugyanazon erőforrásokat elérni, ami a helytelen alkalmazás teljesítményhez vezethet.

Ezt egyszerű példával magyarázzuk.

Létre kell hoznunk egy olyan programot, amely műveleteket végez bankszámlával. A számláról történő bizonyos pénzösszeg visszavonásának működése a következő sorrendben fordulhat elő:
  • az első lépés ellenőrzi a számlán tárolt összmennyiséget;
  • ha a teljes összeg megegyezik vagy meghaladja a visszavont pénzösszeg összegét, a teljes összeget csökkentik a szükséges összeggel;
  • a mérleg értéke a folyószámlára van írva.

Ha a folyószámla csökkentésének működése egyszálú rendszerben történik, akkor nem jelent problémát. Ugyanakkor képzeljük el, hogy két folyamat megpróbálja végrehajtani ugyanazt a műveletet egyszerre. Legyen a számlán 5 millió dollár, és mindkét folyamat megpróbálja eltávolítani tőle 3 millió dollárt.

Tegyük fel, hogy az események az alábbiak szerint bontakoznak ki:
  • Az első folyamat ellenőrzi a folyó fizetési mérleg állapotát, és ellenőrzi, hogy 5 millió dollárral rendelkezik;
  • a második folyamat ellenőrzi a folyó fizetési mérleg állapotát, és biztosítja, hogy 5 millió dollárt tartson;
  • az első folyamat 3 millió dollárral csökkenti a számlát, és nyilvántartja a folyó fizetési mérleg egyenlegét (2 millió dollár);
  • a második folyamat ugyanazt a műveletet hajtja végre, mivel ellenőrzése után úgy véli, hogy a számla még mindig 5 millió dollárt tartalmaz.

Ennek eredményeként kiderült, hogy 6 millió dollárt visszavontak a számláról, amelyen 5 millió dollár volt, és még mindig 2 millió dollár maradt! Összesen - a bank kárt okozott 3 millió dollár.

Hogyan készítsünk egy programot a számla csökkentésére, így nem engedte fel ilyen módon?

Nagyon egyszerű - a számlán végzett műveletek időtartamára egy folyamathoz szükséges megtiltani a fiókhoz való hozzáférést más folyamatokból. Ebben az esetben a program forgatókönyve a következőképpen alakul:
  • a folyamat blokkolja a számlákat a műveletek más folyamatok végrehajtásával, kizárólagos tulajdonlásával;
  • a folyamat végrehajtja a számla csökkentésére irányuló eljárást, és a folyó fizetési mérlegre új egyenlegértéket ír le;
  • A folyamat feloldja a fiókot, lehetővé téve más folyamatok műveletek végrehajtását.

Amikor az első folyamat blokkolja a fiókot, az nem érhető el más folyamatokhoz. Ha a második folyamat is megpróbálja blokkolni ugyanazt a fiókot, akkor várakozási állapotba kerül. Amikor az első folyamat csökkenti a számlát, és 2 millió dollár marad, a második folyamat feloldásra kerül. Ellenőrzi az egyensúlyt, győződjön meg arról, hogy az összeg nem elegendő, és nem végzi el a műveletet.

Így egy többszálas környezetben szálakat kell szinkronizálni a kritikus erőforrások elérésekor. Ha a rossz sorrendű műveletek végrehajtása ilyen erőforrásokon történik, akkor ez nehezen megtalálható hibákat eredményez.

A Java programozási nyelvben számos eszköz van a szálak szinkronizálására, amelyeket most nézünk.

A módszerek szinkronizálása

A szinkronizálás lehetősége minden Java-alkalmazás által létrehozott objektumra épül. Ehhez az objektumok zárakkal vannak ellátva, amelyek segítségével blokkolhatja az ezekhez az objektumokhoz hozzáférő áramokat.

A reteszek használatához a megfelelő módszert szinkronizálhatja. szinkronizálva:

Amikor egy szinkronizált eljárást hívunk meg, a megfelelő objektumot (amelyben definiáljuk) blokkoljuk más szinkronizált módszerek használatára. Ennek eredményeként megakadályozható, hogy az objektum memóriaterületén két értékmódosítással egyidejűleg rögzítsük az adatokat.

A szinkronizált módszerek használata egyszerű módja annak, hogy szinkronizálja azokat a szálakat, amelyek közös kritikus erőforrásokat használnak, például a fent leírt bankszámlát.

Ne feledje, hogy nem szükséges az egész módszer szinkronizálása - csak kritikus kódot szinkronizálhatsz.

Itt a szinkronizálás a Számlakód esetében történik.

Áramlás-blokkolás

A szinkronizált szálat szinkronizált szálat automatikusan lezárt állapotba lehet kapcsolni egy másik szinkronizált eljárás által elfoglalt erőforrás elérése, illetve bizonyos bemeneti vagy kimeneti műveletek végrehajtása során. Bizonyos esetekben azonban célszerű még finomabb szinkronizálási eszközöket alkalmazni, amelyek lehetővé teszik a kifejezetten alkalmazás-on-demand használatát.

A blokkolás egy meghatározott ideig

Az alvás mód használatával blokkolhatja az áramlást egy meghatározott időtartamra:

Ebben a példában a menetcérna 500 milliszekundumban leáll. Vegye figyelembe, hogy várakozás közben a felfüggesztett szál nem veszi fel a CPU erőforrásait.

Mivel az alvásmód létrehozhat egy MegszakítottExceptet, meg kell adni annak feldolgozását. Ehhez a próbálkozási és fogási záradékokat használtuk.

A munka ideiglenes felfüggesztése és újraindítása

A módszerek felfüggesztése és folytatása lehetővé teszi, hogy átmenetileg felfüggeszti és folytatja a munkafolyamat munkáját.

A következő kódrészletben az m_Rectangles szál leállítja a munkáját, amikor az egérmutató az appletablak fölött van:

A szál munkája folytatódik, amikor az egérkurzor kilép az applet ablakból:

Várakozás az értesítésre

Ha a szálak kölcsönhatását olyan módon kell megszervezni, hogy egy szál vezérelje egy másik vagy más szálak működését, használhatja a várakozási módokat. értesíteni és értesíteni az összeset. az objektum osztályában definiált.

A várakozási mód paraméter vagy paraméter nélkül használható. Ez a módszer átalakítja a szálat egy várakozási állapotba, amelyben mindaddig marad, amíg a bejelentés értesül, a notifyAll módszer a szálat jelzi, vagy amíg a várakozási paraméterben megadott időtartam lejárt.

Hogyan használhatjuk a várakozást, értesítést és értesítéseket?

A várakozási állapotba helyezett módszert szinkronizálni kell, azaz szinkronizálni kell:

Ebben a példában a futási módban egy hurok van definiálva, amely paraméterek nélkül hívja a várakozási módot. Minden alkalommal, amikor a következő hurok átkerül, a futási mód várakozási állapotba kerül, míg egy másik szál végrehajtja a bejelentést a bejelentési módszerrel.

Az alábbiakban egy olyan szálat adtunk meg, amely a bejelentési módot hívja:

Megjegyezzük, hogy annak ellenére, hogy maga a futtatási módszer nem szinkronizálva van, a bejelentett módszert hívja szinkronizált üzemmódban. A szinkronizációs objektum a szál, amelyre a bejelentési módot nevezik.

Várja a szál befejezését

A csatlakozási módszer használatával várhat a szál befejezésére. amelyre ezt a módszert nevezik.

A csatlakozási módszer három definíciója van:

Az első közülük várakozik időhatár nélkül, a második, a várakozást erőszakkal megszakítják milliszekundus milliszekundum után, harmadszor és harmincmásodperc és nanos nanoszekundumban. Felhívjuk a figyelmet arra, hogy a valóságban nem tudod megadni az időt a nanoszekundum pontosságához, mivel a számítógép rendszeridőzítőjének diszkrétsége sokkal nagyobb.

Kapcsolódó cikkek