Java vlákna


Java vlákna

Vlákna umožňují programu pracovat efektivněji tím, že dělá více věcí současně.

Vlákna lze použít k provádění složitých úkolů na pozadí bez přerušení hlavního programu.


Vytvoření vlákna

Vlákno lze vytvořit dvěma způsoby.

Lze jej vytvořit rozšířením Threadtřídy a přepsáním její run() metody:

Rozšířit syntaxi

public class Main extends Thread {
  public void run() {
    System.out.println("This code is running in a thread");
  }
}

Dalším způsobem, jak vytvořit vlákno, je implementace Runnablerozhraní:

Implementujte syntaxi

public class Main implements Runnable {
  public void run() {
    System.out.println("This code is running in a thread");
  }
}

Běžící vlákna

Pokud třída rozšiřuje Threadtřídu, vlákno lze spustit vytvořením instance třídy a voláním její start()metody:

Rozšířit příklad

public class Main extends Thread {
  public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    System.out.println("This code is outside of the thread");
  }
  public void run() {
    System.out.println("This code is running in a thread");
  }
}

Pokud třída implementuje Runnablerozhraní, vlákno lze spustit předáním instance třídy Threadkonstruktoru objektu a následným voláním metody vlákna start():

Příklad implementace

public class Main implements Runnable {
  public static void main(String[] args) {
    Main obj = new Main();
    Thread thread = new Thread(obj);
    thread.start();
    System.out.println("This code is outside of the thread");
  }
  public void run() {
    System.out.println("This code is running in a thread");
  }
}

Rozdíly mezi „rozšiřováním“ a „implementací“ vláken

Hlavní rozdíl je v tom, že když třída rozšiřuje třídu Thread, nemůžete rozšířit žádnou jinou třídu, ale implementací rozhraní Runnable je možné rozšířit také z jiné třídy, například: class MyClass extends OtherClass implements Runnable.


Problémy souběžnosti

Protože vlákna běží současně s ostatními částmi programu, neexistuje způsob, jak zjistit, v jakém pořadí bude kód běžet. Když vlákna a hlavní program čtou a zapisují stejné proměnné, hodnoty jsou nepředvídatelné. Problémy, které z toho vyplývají, se nazývají problémy souběžnosti.

Příklad

Příklad kódu, kde je hodnota proměnné částky nepředvídatelná:

public class Main extends Thread {
  public static int amount = 0;

  public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    System.out.println(amount);
    amount++;
    System.out.println(amount);
  }

  public void run() {
    amount++;
  }
}

Abyste se vyhnuli problémům se souběžností, je nejlepší sdílet mezi vlákny co nejméně atributů. Pokud je potřeba sdílet atributy, jedním z možných řešení je použít isAlive() metodu vlákna ke kontrole, zda vlákno skončilo běh, před použitím atributů, které může vlákno změnit.

Příklad

Použijte isAlive(), abyste předešli problémům souběžnosti:

public class Main extends Thread {
  public static int amount = 0;

  public static void main(String[] args) {
    Main thread = new Main();
    thread.start();
    // Wait for the thread to finish
    while(thread.isAlive()) {
    System.out.println("Waiting...");
  }
  // Update amount and print its value
  System.out.println("Main: " + amount);
  amount++;
  System.out.println("Main: " + amount);
  }
  public void run() {
    amount++;
  }
}