Java szálak

A Wikipédiából, a szabad enciklopédiából

A Java nyelvi környezet alkalmas több szálú programok készítésére, futtatására.

Szálak használata[szerkesztés | forrásszöveg szerkesztése]

A Java programozási nyelvben a szálak tipikus használata a következő esetek indokolják:

  • a program gyorsítására, oly módon, hogy a nagyobb teendőket egy-egy szálba rendezhetők,így a megfelelő ütemezés mellett a program futási ideje rövidülhet.
  • a program egy száljának rövid idejű felfüggesztésére.

A szál felfüggesztését a Thread osztály sleep metódusa meghívásával oldható meg, aminek argumentumként szál/program felfüggesztésének idejét kell megadni (ezredmásodpercben). Mindez a szálak összehangolására is használható.

Pl: Thread.sleep(1000); Itt az adott szál futása 1 másodpercig lesz felfüggesztve.

Szálak létrehozása[szerkesztés | forrásszöveg szerkesztése]

Egy szál létrehozásának két lehetséges módja van:

  • Örököltethető a Thread osztályból az új osztály, melynek a run metódust kell felüldefiniálni,
  • Létrehozható a Runnable interfész implementálásával, amit át kell adni a Thread konstruktorának, ezután már el lehet indítani szálat a start metódussal.

Példa ez utóbbira:

  public class TestThread implements Runnable {
    public void run () {
      System.out.println("Helló világ");
    }
 
    public static void main (String[] args) {
      Thread thread = new Thread(new TestThread());
      thread.start();
    }
  }

Szinkronizáció[szerkesztés | forrásszöveg szerkesztése]

Egy többszálú java program egyszerre számos feladatot tud végrehajtani, függetlenül a processzormagok számától. A programok futtatásáért felelős JVM (Java virtuális gép az angol Java Virtual Machine rövidítése) a saját ütemezője szerint választja ki, hogy éppen melyik szálat futtatja. Mindez JVM implementáció függő, amely befolyásolható több módon is:

  • A Thread.sleep(); utasítással várakoztathatók / időzíthetők a különböző szálak. Például: két vagy több szálat használó program esetén, hogy a szálakat ne zavarják egymást. Az egyiket/többit elaltatjuk annyi időre hogy akkor "ébredjen(ek) fel", mikor a másik befejezte munkáját.
  • Vannak olyan helyzetek, mikor azt szeretnénk hogy egy objektumot a konzisztencia érdekében egyszerre csak egy szál használhasson. Ez a synchronized kulcsszó használatával valósítható meg. Az objektum szinkronizálható egy metódushívás vagy egy utasításblokk idejére.

Az alábbi példában a saját objektum blokkolódik más szálak számára a Hello metódus végrehajtása alatt:

  public synchronized void Hello() {
    System.out.println("Hello világ!");
  }

A blokkszintű szinkronizáció esetében tetszőleges blokkolandó objektum is megadható. A saját objektum blokkolásához nem kell megadni nevesített objektumot ill. explicit módon a this kulcsszó is használható erre a célra.

A szinkronizáció a memóriaszervezést is érinti. A JVM minden szál számára saját memória-gyorsítótárat tart fenn. A szinkronizált programrészek végrehajtása alatt minden adatmódosítás kizárólag a gyorsítótárat érinti, kivéve ha az adott objektum volatile, azaz nem gyorstárazható. Így az olvasási blokkolás nem is szükséges, tehát végeredményben csak az adott metódus kerül teljes blokkolásra.

Új lehetőségek[szerkesztés | forrásszöveg szerkesztése]

A java 1.5-től új szinkronizációs lehetőségeket kínál, nem nyelvi szinten, hanem új osztálykönyvtár biztosításával:

Task Scheduling Framework: az Executor-ok segítségével jobban szervezhetők például az opcionálisan időzített szálak

Concurrent Collections: a szokásos gyűjteménytípusok szálbiztos változatait tartalmazza

Atomic Variables: lehetőség összetett atomi műveleteket támogató változók használatára (pl. növelés és lekérdezés; összehasonlítás és beállítás)

Synchronizers: a szálak közötti koordinációt segítő osztályok (Semaphor, Mutex, Barrier, Latch és Exchanger)

Locks: explicit lockolási lehetőségek

Nanosecond-granularity timing: nanoszekudumos pontosságú időmérés, időzítés lehetősége