Ugrás a tartalomhoz

Java-szálak

A Wikipédiából, a szabad enciklopédiából
A lap korábbi változatát látod, amilyen Bináris (vitalap | szerkesztései) 2015. június 13., 08:54-kor történt szerkesztése után volt. Ez a változat jelentősen eltérhet az aktuális változattól. (A volatile magyarul volatilisnek fordítható)

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

Szálak használata

A Java programozási nyelvben a szálakat tipikusan a következő célokra használják:

  • a program gyorsítására, oly módon, hogy a nagyobb teendők 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ése 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

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ó

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ő, és 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 (vagy a 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("Helló, 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 volatilis, 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

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