3.1 Aktív objektum
Az aktív objektum egy tervezési minta, amely elválasztja a metódus végrehajtási szálát attól a száltól, amelyben meghívták. Ennek a mintának az a célja, hogy párhuzamos végrehajtást biztosítson aszinkron metódushívások és kérésfeldolgozás ütemező használatával.
Egyszerűsített változat:
Klasszikus változat:
Ez a sablon hat elemből áll:
- Proxy objektum, amely interfészt biztosít az ügyfél nyilvános metódusaihoz.
- Egy interfész, amely meghatározza az aktív objektum hozzáférési módszereit.
- Az ügyfelektől beérkező kérések listája.
- Egy ütemező, amely meghatározza a lekérdezések végrehajtásának sorrendjét.
- Aktív objektum metódusok megvalósítása.
- Visszahívási eljárás vagy változó, amellyel az ügyfél megkapja az eredményt.
3.2 zár
A zárolási minta egy szinkronizálási mechanizmus, amely lehetővé teszi a több szál közötti megosztott erőforráshoz való kizárólagos hozzáférést. A zárak az egyidejűség-ellenőrzési politika érvényesítésének egyik módja.
Alapvetően lágy zárolást használnak, azzal a feltételezéssel, hogy minden szál megpróbálja „megszerezni a zárat”, mielőtt hozzáférne a megfelelő megosztott erőforráshoz.
Egyes rendszerek azonban biztosítanak egy kötelező zárolási mechanizmust, amellyel a zárolt erőforráshoz való jogosulatlan hozzáférési kísérlet megszakad, és kivételt dob a hozzáférést megkísérlő szálra.
A szemafor a zár legegyszerűbb típusa. Az adatelérés szempontjából nem teszünk különbséget a hozzáférési módok között: megosztott (csak olvasási) vagy exkluzív (írás-olvasás). Megosztott módban több szál kérhet zárolást, hogy csak olvasható módban hozzáférjen az adatokhoz. A kizárólagos hozzáférési módot a frissítési és törlési algoritmusok is használják.
A zárak típusait az a stratégia különbözteti meg, amely blokkolja a szál végrehajtásának folytatását. A legtöbb megvalósításban a zárolási kérés megakadályozza, hogy a szál továbbra is fusson, amíg a zárolt erőforrás elérhetővé nem válik.
A spinlock egy olyan zár, amely egy hurokban vár, amíg a hozzáférést megadják. Az ilyen zárolás nagyon hatékony, ha egy szál kis ideig vár a zárra, így elkerülhető a szálak túlzott átütemezése. A hozzáférésre való várakozás költsége jelentős lesz, ha az egyik szál hosszú ideig tartja a zárat.
A zárszerkezet hatékony megvalósításához hardverszintű támogatás szükséges. A hardvertámogatás megvalósítható egy vagy több atomi műveletként, mint például a "teszt-és-beállítás", "fetch-and-add" vagy "compare-and-swap". Az ilyen utasítások lehetővé teszik, hogy megszakítás nélkül ellenőrizze, hogy a zár szabad-e, és ha igen, akkor szerezze be a zárat.
3.3 Monitor
A Monitor minta egy magas szintű folyamat interakciós és szinkronizálási mechanizmus, amely hozzáférést biztosít a megosztott erőforrásokhoz. Két vagy több számítógépes feladat szinkronizálásának módszere egy közös erőforrás, általában hardver vagy változókészlet használatával.
A monitor alapú többfeladatos munkavégzés során a fordító vagy értelmező transzparensen illeszti be a zár-feloldó kódot a megfelelően formázott rutinokba, transzparens módon a programozó számára, megkímélve a programozót attól, hogy kifejezetten szinkronizációs primitíveket hívjon.
A monitor a következőkből áll:
- eljárások halmaza, amelyek kölcsönhatásba lépnek egy megosztott erőforrással
- mutex
- ehhez az erőforráshoz társított változók
- egy invariáns, amely feltételeket határoz meg a versenyfeltételek elkerülésére
A felügyeleti eljárás a munka megkezdése előtt felveszi a mutexet, és addig tartja, amíg az eljárás ki nem lép, vagy amíg egy bizonyos feltételt be nem vár. Ha minden egyes eljárás garantálja, hogy az invariáns igaz a mutex feloldása előtt, akkor egyetlen feladat sem szerezheti meg az erőforrást versenyhelyzetben.
Így működik a szinkronizált operátor Java-ban a wait()
és metódusokkal notify()
.
3.4 A reteszelés kétszeri ellenőrzése
A duplán ellenőrzött zár egy párhuzamos tervezési minta, amelynek célja a zár megszerzésének többletköltsége csökkentése.
Először a blokkolási feltételt szinkronizálás nélkül ellenőrzik. Egy szál csak akkor próbál meg zárolást szerezni, ha az ellenőrzés eredménye azt jelzi, hogy meg kell szereznie a zárolást.
//Double-Checked Locking
public final class Singleton {
private static Singleton instance; //Don't forget volatile modifier
public static Singleton getInstance() {
if (instance == null) { //Read
synchronized (Singleton.class) { //
if (instance == null) { //Read Write
instance = new Singleton(); //
}
}
}
}
Hogyan hozzunk létre egyszemélyes objektumot szálbiztos környezetben?
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
}
Ha különböző szálakból hoz létre egy Singleton objektumot, akkor előfordulhat, hogy több objektum jön létre egyszerre, és ez elfogadhatatlan. Ezért ésszerű az objektum létrehozását egy szinkronizált utasításba csomagolni.
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
Ez a megközelítés működni fog, de van egy kis hátránya. Az objektum létrehozása után minden alkalommal, amikor megpróbálja megszerezni a jövőben, a szinkronizált blokkban ellenőrzés történik, ami azt jelenti, hogy az aktuális szál és minden, ami hozzá kapcsolódik, zárolásra kerül. Tehát ez a kód egy kicsit optimalizálható:
public static Singleton getInstance() {
if (instance != null)
return instance;
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
Egyes nyelveken és/vagy egyes gépeken nem lehetséges ezt a mintát biztonságosan megvalósítani. Ezért néha anti-mintának is nevezik. Az ilyen jellemzők a „megtörténik korábban” szigorú sorrendű kapcsolat megjelenéséhez vezettek a Java memóriamodellben és a C++ memóriamodellben.
Általában arra szolgál, hogy csökkentse a többszálú programok, például a Singleton tervezési minta, lusta inicializálás végrehajtásával járó többletköltséget. Egy változó lusta inicializálása esetén az inicializálást addig halasztják, amíg a változó értékére szükség lesz a számításban.
3.5 Ütemező
Az ütemező egy párhuzamos tervezési minta, amely mechanizmust biztosít egy ütemezési házirend megvalósításához, de független minden konkrét házirendtől. Azt a sorrendet szabályozza, amelyben a szálak szekvenciális kódot hajtsanak végre egy olyan objektum használatával, amely kifejezetten meghatározza a várakozó szálak sorrendjét.
GO TO FULL VERSION