Többszálas Java oktatóanyag példákkal

Tartalomjegyzék:

Anonim

Bármely alkalmazásnak több folyamata lehet (példány). Ennek a folyamatnak mindegyike hozzárendelhető egyetlen szálként vagy több szálként. Ebben az oktatóanyagban megtudhatjuk, hogyan lehet több feladatot egyidejűleg végrehajtani, és többet is megtudhatunk a szálakról és a szálak közötti szinkronizálásról.

Ebben az oktatóanyagban megtanuljuk:

  • Mi az egyetlen szál
  • Mi a multithreading a Java-ban?
  • Menet életciklus Java-ban
  • Java szál szinkronizálása
  • Java többszálas példa

Mi az egyszálas?

Az egyetlen szál alapvetően könnyű és a legkisebb feldolgozási egység. A Java szálakat használ a "Szálosztály" használatával.

Kétféle szál létezik - felhasználói szál és démon szál (a démon szálakat akkor használjuk, amikor az alkalmazást meg akarjuk tisztítani, és a háttérben használjuk őket).

Amikor egy alkalmazás először elindul, felhasználói szál jön létre. Tegye ezt közzé, sok felhasználói szálat és démon szálat hozhatunk létre.

Egyszálas példa:

csomag demotest;nyilvános osztály GuruThread{public static void main (String [] érvel) {System.out.println ("egyetlen szál");}}

Az egyetlen szál előnyei:

  • Csökkenti az alkalmazás általános költségeit, mivel az egyszálú végrehajtás a rendszerben történik
  • Emellett csökkenti az alkalmazás karbantartási költségeit.

Mi a multithreading a Java-ban?

A MULTITHREADING a Java-ban két vagy több szál egyidejű végrehajtása a CPU maximális kihasználása érdekében. A többszálas alkalmazások két vagy több szálat futtatnak egyidejűleg. Ezért a Java-ban Concurrency néven is ismert. Minden szál párhuzamosan fut egymással. A több szál nem külön memóriaterületet oszt ki, ezért mentik a memóriát. A szálak közötti kontextusváltás is kevesebb időt vesz igénybe.

Példa több szálra:

csomag demotest;nyilvános osztály GuruThread1 megvalósítja Runnable{public static void main (String [] érvel) {Szál guruThread1 = új szál ("Guru1");Szál guruThread2 = új szál ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("A szálnevek a következők:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@ Felülíráspublic void run () {}}

A többszálas előnyök:

  • A felhasználókat nem blokkoljuk, mert a szálak függetlenek, és időnként több műveletet is elvégezhetünk
  • Mivel a szálak függetlenek, a többi szálat nem érinti, ha az egyik szál kivételnek felel meg.

Menet életciklus Java-ban

A szál életciklusa:

A szál életciklusának különböző szakaszai vannak, amint azt a fenti ábra mutatja:

  1. Új
  2. Futható
  3. Futás
  4. Várakozás
  5. Halott
  1. Új: Ebben a szakaszban a szál a "Thread class" osztály segítségével jön létre. Ez addig az állapotig marad, amíg a program elindítja a szálat. Született szálnak is nevezik.
  2. Futtatható: Ezen az oldalon a szál példányát egy indítási módszerrel hívják meg. A szálvezérlést az ütemező kapja meg a végrehajtás befejezéséhez. Az ütemezőtől függ, hogy futtatja-e a szálat.
  3. Futás: Amikor a szál végrehajtani kezdi, akkor az állapot "futó" állapotra változik. Az ütemező kiválaszt egy szálat a szálkészletből, és elkezdi végrehajtani az alkalmazásban.
  4. Várakozás: Ez az az állapot, amikor egy szálnak várnia kell. Mivel az alkalmazásban több szál fut, szinkronizálásra van szükség a szálak között. Ezért az egyik szálnak meg kell várnia, amíg a másik szál végrehajtásra kerül. Ezért ezt az állapotot várakozási állapotnak nevezzük.
  5. Dead: Ez az az állapot, amikor a szál leáll. A szál futó állapotban van, és amint befejezte a feldolgozást, "holt állapotban" van.

A szálak általában használt módszerei a következők:

Módszer Leírás
Rajt() Ez a módszer elindítja a szál végrehajtását, és a JVM meghívja a run () metódust a szálon.
Alvás (milliszekundumban) Ezzel a módszerrel a szál alvó állapotba kerül, így a szál végrehajtása ezredmásodpercekig szünetel, és ezt követően ismét a szál futtatni kezd. Ez segít a szálak szinkronizálásában.
getName () Visszaadja a szál nevét.
setPriority (int newpriority) Megváltoztatja a szál prioritását.
hozam () A leállításban lévő szálak és más szálak végrehajtását okozza.

Példa: Ebben a példában létrehozunk egy szálat, és feltárjuk a szálakhoz rendelkezésre álló beépített módszereket.

csomag demotest;public class thread_example1 megvalósítja a Runnable {@ Felülíráspublic void run () {}public static void main (String [] érvel) {Szál guruthread1 = új Szál ();guruthread1.start ();próbáld ki {guruthread1.sleep (1000);} catch (InterruptedException e) {// TODO Automatikusan létrehozott fogási blokke.printStackTrace ();}guruthread1.setPriority (1);int gurupriority = guruthread1.getPriority ();System.out.println (gurupriority);System.out.println ("Szál futása");}}

A kód magyarázata:

  • 2. kódsor : Létrehozunk egy "thread_Example1" osztályt, amely a Futható felületet valósítja meg (ezt minden olyan osztálynak meg kell valósítania, amelynek példányait a szál futtatni kívánja.)
  • 4. kódsor : Ez felülírja a futtatható felület futási módszerét, mivel kötelező ezt felülbírálni
  • 6. kódsor: Itt definiáltuk azt a fő módszert, amellyel megkezdjük a szál végrehajtását.
  • 7. kódsor : Itt új szálnevet hozunk létre "guruthread1" néven egy új szálosztály példányosításával.
  • 8. kódsor: a szál "start" módszerét fogjuk használni a "guruthread1" példány használatával. Itt a szál elkezdi végrehajtani.
  • 10. kódsor : Itt a szál "alvás" módszerét használjuk a "guruthread1" példány használatával. Ezért a szál 1000 ezredmásodpercig alszik.
  • 9-14. Kód: Itt az alvás módszert helyeztük el a try catch blokkban, mivel van egy bejelölt kivétel, amely megszakadt kivétel.
  • 15. kódsor: Itt a szál prioritását 1-re állítjuk, attól függetlenül, hogy melyik volt a prioritás
  • 16. kódsor : Itt kapjuk meg a szál prioritását a getPriority () használatával
  • 17. kódsor : Itt kinyomtatjuk a getPriority fájlból letöltött értéket
  • 18. kódsor: Itt egy szöveget írunk, amelyen a szál fut.

A fenti kód végrehajtásakor a következő kimenetet kapja:

Kimenet:

Az 5 a Szál prioritása, a Szál futása pedig a szöveg, amely a kódunk kimenete.

Java szál szinkronizálása

A többszálas szálon a programok aszinkron viselkedése van. Ha az egyik szál adatot ír, és egy másik szál, amely egyszerre olvas adatokat, az következetlenséget okozhat az alkalmazásban.

Ha két vagy több szálon keresztül kell hozzáférni a megosztott erőforrásokhoz, akkor a szinkronizálási megközelítést alkalmazzák.

A Java szinkronizált módszereket biztosított a szinkronizált viselkedés megvalósításához.

Ebben a megközelítésben, ha a szál eléri a szinkronizált blokkot, akkor egyetlen másik szál sem hívhatja meg ezt a módszert ugyanazon az objektumon. Minden szálnak meg kell várnia, amíg az a szál befejezi a szinkronizált blokkot, és ebből kijön.

Ily módon a szinkronizálás segít egy többszálas alkalmazásban. Az egyik szálnak meg kell várnia, amíg egy másik szál befejezi a végrehajtását, csak akkor engedélyezik a többi szál végrehajtását.

A következő formában írható:

Szinkronizált (objektum){// Szinkronizálandó utasítások blokkja}

Java többszálas példa

Ebben a példában két szálat veszünk, és lekérjük a szál nevét.

1. példa:

GuruThread1.javacsomag demotest;a GuruThread1 nyilvános osztály megvalósítja a Runnable {/ *** @param érvel* /public static void main (String [] érvel) {Szál guruThread1 = új szál ("Guru1");Szál guruThread2 = új szál ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("A szálnevek a következők:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@ Felülíráspublic void run () {}}

A kód magyarázata:

  • 3. kódsor : Vettünk egy "GuruThread1" osztályt, amely a Runnable-t valósítja meg (ezt minden olyan osztálynak végre kell hajtania, amelynek példányait a szál futtatni kívánja.)
  • 8. kódsor: Ez az osztály fő módszere
  • 9. kódsor : Itt példázzuk a Thread osztályt, létrehozunk egy példányt, amelynek neve "guruThread1", és létrehozunk egy szálat.
  • 10. kódsor : Itt példázzuk a Thread osztályt, létrehozunk egy "guruThread2" nevű példányt, és létrehozunk egy szálat.
  • 11. kódsor : Elindítjuk a szálat, azaz a guruThread1.
  • 12. kódsor : Elindítjuk a szálat, azaz a guruThread2.
  • 13. kódsor : A szöveg kiírása "A szálnevek a következők:"
  • 14. kódsor : Az 1. szál nevének megszerzése a szálosztály getName () metódusával.
  • 15. kódsor: A 2. szál nevének megszerzése a szálosztály getName () metódusával.

A fenti kód végrehajtásakor a következő kimenetet kapja:

Kimenet:

A szálneveket itt adják ki

  • Guru1
  • Guru2

2. példa:

Ebben a példában megismerjük a futható interfész run () és start () metódusainak felülbírálását, és létrehozunk az adott osztály két szálát, és ennek megfelelően futtatjuk őket.

Két osztályt is veszünk,

  • A futó felületet megvalósító és
  • Egy másik, amelyik a fő módszerrel rendelkezik, és ennek megfelelően fog végrehajtani.
csomag demotest;nyilvános osztály GuruThread2 {public static void main (String [] érvel) {// TODO Automatikusan létrehozott módszercsonkGuruThread3 threadguru1 = új GuruThread3 ("guru1");threadguru1.start ();GuruThread3 threadguru2 = új GuruThread3 ("guru2");threadguru2.start ();}}A GuruThread3 osztály megvalósítja a Runnable {Szál guruthread;privát String guruname;GuruThread3 (karakterlánc neve) {guruname = név;}@ Felülíráspublic void run () {System.out.println ("Szál fut" + guruname);mert (int i = 0; i <4; i ++) {System.out.println (i);System.out.println (guruname);próbáld ki {Szál.alszik (1000);} catch (InterruptedException e) {System.out.println ("A szál megszakadt");}}}public void start () {System.out.println ("A szál elindult");if (guruthread == null) {guruthread = új szál (ez, guruname);guruthread.start ();}}}

A kód magyarázata:

  • 2. kódsor : Itt egy "GuruThread2" osztályt veszünk, amelyben a fő módszer lesz.
  • 4. kódsor: Itt az osztály fő módszerét vesszük.
  • 6-7. Kódsor : Itt létrehozzuk a GuruThread3 osztály egy példányát (amely a kód alábbi soraiban jön létre) "threadguru1" néven, és elindítjuk a szálat.
  • 8-9. Kódsor : Itt létrehozunk egy újabb példányt a GuruThread3 osztályról (amely a kód alábbi soraiban jön létre) "threadguru2" néven, és elindítjuk a szálat.
  • 11. kódsor : Itt létrehozunk egy "GuruThread3" osztályt, amely a futható felületet valósítja meg (ezt minden olyan osztálynak végre kell hajtania, amelynek példányait a szál futtatni kívánja.)
  • Kódsor 13-14: két osztályváltozót veszünk, amelyek közül az egyik a type thread osztályba, a másik pedig a string osztályba tartozik.
  • 15-18 kódsor : felülbíráljuk a GuruThread3 konstruktort, amely egy argumentumot vesz string karakterláncnak (ami a szálak neve), amelyet a guruname osztályváltozóhoz rendelnek, és így a szál neve tárolódik.
  • 20. kódsor: Itt felülírjuk a futható felület run () metódusát.
  • Kódsor 21: A szál nevét a println utasítás segítségével adjuk meg.
  • Kódsor 22-31: Itt egy for ciklust használunk, amelynek számlálója 0-ra inicializálva van, és nem lehet kevesebb 4-nél (tetszőleges számot vehetünk, így a hurok négyszer fog futni), és növekszik a számláló. Kinyomtatjuk a szál nevét, és a szálat 1000 milliszekundumig alszik egy próbálkozási blokkon belül, mivel az alvási módszer ellenőrzött kivételt jelent.
  • 33. kódsor: Itt felülírjuk a futtatható felület start módszerét.
  • 35. kódsor : Kibocsátjuk a "Téma elindult" szöveget.
  • Kódsor 36-40: Itt veszünk egy if feltételt annak ellenőrzésére, hogy a guruthread osztályváltozónak van-e értéke vagy sem. Ha null értéke, akkor egy szálosztályt használva létrehozunk egy példányt, amely a nevet paraméterként veszi fel (amelynek értékét a konstruktorban rendelték hozzá). Ezután a szál elindul a start () metódussal.

A fenti kód végrehajtásakor a következő kimenetet kapja:

Kimenet :

Két szál van, ezért kétszer kapjuk meg a "Thread started" üzenetet.

A szál nevét akkor kapjuk meg, amikor kinyomtattuk őket.

A ciklusra megy, ahol a számlálót és a szál nevét nyomtatjuk, és a számláló 0-val kezdődik.

A hurok háromszor fut le, és a szál 1000 milliszekundumig alszik.

Ezért először megkapjuk a guru1-et, majd a guru2-t, majd ismét a guru2-t, mert a szál itt alszik 1000 ezredmásodpercig, majd a következő guru1 és ismét guru1, a szál 1000 ezredmásodpercig alszik, tehát megkapjuk a guru2-t, majd a guru1-et.

Összegzés :

Ebben az oktatóanyagban többszálas alkalmazásokat láttunk a Java-ban, valamint az egy- és többszálas használatának módját.

  • Többszálas szál esetén a felhasználókat nem blokkolják, mivel a szálak függetlenek, és egyszerre több műveletet is képesek végrehajtani
  • A szál életciklusának különböző szakaszai:
    • Új
    • Futható
    • Futás
    • Várakozás
    • Halott
  • Ismerkedtünk a szálak közötti szinkronizálással is, amelyek segítik az alkalmazás zavartalan működését.
  • A többszálas kezelés megkönnyíti az alkalmazás sok más feladatát.