Haladó Java kurzus

Bevezető

Szálat indítani több módon is lehetséges:

  1. 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
          }
    }
  2. 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
          }
    }
  3. 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:

Feladatok

  1. 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)).

  2. 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.

  3. 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.