Szálat indítani több módon is lehetséges:
Thread-ből származtatással:
class MyThread extends Thread {
@Override
public void run() {
...
}
}
class Program {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start(); // elindul a szál, futtatja a run()-t
}
}Runnable implementálásával:
class Task implements Runnable {
@Override
public void run() {
...
}
}
class Program {
public static void main(String[] args) {
Task task = new Task(); // t-nek nincs start() metódusa
// mt.start(); // fordítási hiba
Thread t = new Thread(task);
t.start() // elindul a sál, futtatja task.run()-t
}
}Lambda függvénnyel:
class Program {
public static void main(String[] args) {
Thread t = new Thread(() -> {
... // paraméter nélküli, void eredményű lambda
});
t.start() // elindul a sál, futtatja a lambdát
}
}A szinkronizációnak Javában két szerepe van:
összehangolja a szálak futását: egy szinkronizált metódust vagy blokkot egyszerre csak egy szál hajthat végre. A többinek várnia kell.
megszabja, melyik szál mit lát a memóriában. A szálak saját cache-sel dolgoznak, mely elavulttá válik. A szinkronizációs blokkba való belépéskor a cache-be frissül. Lásd RegularMap és a hozzá tartozó Point osztályokat.
Készíts egy több szálon futó map implementációt!
A parMap paraméterül kap egy sorozatot (tömb vagy lista) és egy egyparaméteres műveletet. A művelet végrehajtása történjen több szálon, minden elemre indítsunk egy szálat. Az eredmények begyűjtése sorban történjen: ha a sorozat x1, x2, x3 volt és a művelet f, akkor az eredmény legyen f(x1), f(x2), f(x3).
A szálak paraméterül kapják a végrehajtandó műveletet, egy xn elemet, az n sorszámot, és egy adatszerkezetet, ahová az eredményt tehetik (például egy Map, melynek tartalma 1 -> f(x1), 2 -> f(x2), 3 -> f(x3)).
Alakítsuk át az előző programot, hogy ExecutorService-t használjon! Ezzel korlátozható az elindított szálak száma, nem lassul be a számítógép.
A szálak visszaadhatják az f(xn) eredményt egy Future objektumon keresztül. Ehhez az ExecutorService submit metódusát használjuk. Ilyenkor nem kell mást átadni a szálaknak, csak a végrehajtandó f műveletet, és egy xn elemet, melyre meghívható f.
Készíts programot, mely fájlokat ír felül véletlenszerű karaktersorozattal. A fájlok írása konkurrensen történjen, minden fájlhoz induljon egy szál. Enter billentyű megnyomására fejeződjön be a fájlok írása. A fájlokat vehetjük paranccsori argumentumokból vagy bekérhetjük a billentyűzetről.
Tipp: a szálak megállításához használjunk AtomicBoolean-t. Rendszeresen nézzük meg az értékét, hogy meg kell-e állni.
Vegyük észre, hogy az AtomicBoolean írásakor és olvasásakor nincs szükség explicit szinkronizációra, mert az a háttérben megtörténik.