Szemafor
A szemaforokat általában akkor használják, ha korlátozni kell a szálak számát a fájlrendszerrel való munka során. A fájlokhoz vagy más megosztott erőforrásokhoz való hozzáférést egy számláló szabályozza. Ha értéke nagyobb, mint nulla, a hozzáférés engedélyezett, ugyanakkor a számláló csökken.
Abban a pillanatban, amikor a számláló nullát ad vissza, az aktuális szál blokkolva lesz, amíg az erőforrást egy másik szál fel nem szabadítja. Az engedélyek száma paramétert a konstruktoron keresztül kell beállítani.
Ezt a paramétert egyenként kell kiválasztania, a számítógép vagy laptop teljesítményétől függően.
public class Main {
public static void main(String[] args) {
Semaphore sem = new Semaphore(1);
CommonResource res = new CommonResource();
new Thread(new MyThread(res, sem, "MyThread_1")).start();
new Thread(new MyThread(res, sem, "MyThread_2")).start();
new Thread(new MyThread(res, sem, "MyThread_3")).start();
}
}
class CommonResource {
int value = 0;
}
class MyThread implements Runnable {
CommonResource commonResource;
Semaphore semaphore;
String name;
MyThread(CommonResource commonResource, Semaphore sem, String name) {
this.commonResource = commonResource;
this.semaphore = sem;
this.name = name;
}
public void run() {
try {
System.out.println(name + "waiting permission");
semaphore.acquire();
commonResource.value = 1;
for (int i = 1; i < 7; i++) {
System.out.println(this.name + ": " + commonResource.value);
commonResource.value++;
Thread.sleep(150);
}
} catch (InterruptedException e) {
System.out.println(e.getMessage() + " " + name);
Thread.currentThread().interrupt();
}
System.out.println(name + "releases permission");
semaphore.release();
}
}
CountDownLatch és mások
CountDownLatch – Lehetővé teszi, hogy több szál várjon, amíg a többi szálon végrehajtott bizonyos számú művelet befejeződik. Példa erre egy alkalmazás telepítése: addig nem indul el, amíg el nem fogadja a használati feltételeket, amíg ki nem választ egy mappát, ahová új programot telepít, és így tovább. Erre van egy speciális countDown() metódus - ez a metódus eggyel csökkenti a visszaszámláló számlálót.
Amint a számlálás nullára megy, a várakozásban lévő összes várakozó szál folytatja a munkáját, és minden további várakozási hívás várakozás nélkül elmúlik. A visszaszámláló számláló egyszeri számláló, és nem állítható vissza.
CyclicBarrier – adott számú szál egy ponton történő szinkronizálására szolgál. A korlátot akkor éri el, amikor N szál meghívja az await(...) metódust és blokkot. Ezt követően a számláló visszaáll az eredeti értékére, és a várakozó szálak felszabadulnak. Ezenkívül szükség esetén egyéni kód futtatható a szálak feloldása és a számláló nullázása előtt. Ehhez a futtatható felület megvalósításával rendelkező objektum átkerül a konstruktoron .
Exchanger<V> — az Exchanger osztály a szálak közötti adatcserére szolgál. Be van gépelve és beírja azt az adattípust, amelyet a szálaknak ki kell cserélniük.
Az adatok cseréje ennek az osztálynak az egyetlen Exchange() metódusával történik :
V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
Az x paraméter a cserélendő adatpuffert jelöli. A metódus második formája meghatározza az időtúllépési paramétert , az időtúllépést és az egységet , az időtúllépési paraméterhez használandó időegység típusát .
A Phaser osztály lehetővé teszi olyan szálak szinkronizálását, amelyek egy átfogó művelet végrehajtásának egyetlen fázisát vagy szakaszát képviselik. A Phaser meghatároz egy szinkronizálási objektumot, amely megvárja, amíg egy bizonyos fázis befejeződik. A Fázis ezután továbblép a következő szakaszra vagy fázisra, és várja, hogy az ismét befejeződjön.
Amikor a Phaser osztállyal dolgozik , gyakran először létre kell hozni az objektumát. Ezután minden résztvevőt regisztrálnunk kell. Az egyes résztvevők regisztrációjához a register() metódust hívják meg , vagy megteheti ezt a módszert anélkül, hogy átadja a szükséges számú résztvevőt a Phaser konstruktornak .
Ezután minden résztvevő végrehajt egy bizonyos műveletsort, amelyek a fázist alkotják. És a Phaser szinkronizáló megvárja, amíg minden résztvevő befejezi a fázis végrehajtását. Ahhoz, hogy értesítse a szinkronizálót, hogy a fázis véget ért, a résztvevőnek meg kell hívnia az érkezés() vagy az érkezésAndAwaitAdvance() metódust . A szinkronizáló ezután a következő fázisra lép.
GO TO FULL VERSION