Vsaka aplikacija ima lahko več procesov (primerkov). Vsakemu od teh postopkov je mogoče dodeliti eno nit ali več niti. V tej vadnici bomo videli, kako izvajati več nalog hkrati, izvedeli pa bomo tudi več o nitih in sinhronizaciji med nitmi.
V tej vadnici bomo izvedeli:
- Kaj je enojna nit
- Kaj je večnitnost v Javi?
- Življenjski cikel niti v Javi
- Sinhronizacija niti Java
- Primer večnitnosti Java
Kaj je enojna nit?
Posamezna nit je v bistvu lahka in najmanjša enota obdelave. Java uporablja niti z uporabo "razreda niti".
Obstajata dve vrsti niti - uporabniška nit in nit demona ( niti demona se uporabljajo, ko želimo očistiti aplikacijo in se uporabljajo v ozadju).
Ko se aplikacija prvič začne, se ustvari uporabniška nit. Objavi, lahko ustvarimo veliko uporabniških niti in demonskih niti.
Primer enojne niti:
demotest paketa;javni razred GuruThread{public static void main (String [] args) {System.out.println ("Ena nit");}}
Prednosti enojnega navoja:
- Zmanjša režijske stroške v aplikaciji, ko se v sistemu izvrši ena nit
- Prav tako zmanjšuje stroške vzdrževanja aplikacije.
Kaj je večnitnost v Javi?
MULTITHREADING v Javi je postopek izvajanja dveh ali več niti hkrati do največje izkoriščenosti CPU. Večnitne aplikacije izvajajo dve ali več niti, ki se izvajajo hkrati. Zato je v Javi znan tudi kot Concurrency. Vsaka nit poteka vzporedno druga z drugo. Večkratne niti ne dodeljujejo ločenega pomnilniškega območja, zato prihranijo pomnilnik. Tudi preklop konteksta med nitmi traja manj časa.
Primer več niti:
demotest paketa;javni razred GuruThread1 izvaja Runnable{public static void main (String [] args) {Thread guruThread1 = nova nit ("Guru1");Thread guruThread2 = nova nit ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("Imena niti so naslednja:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@Overridejavni void run () {}}
Prednosti večnitnosti:
- Uporabniki niso blokirani, ker so niti neodvisne in lahko izvajamo več operacij hkrati
- Ker so niti niti neodvisne, druge niti ne bodo prizadete, če ena nit izpolnjuje izjemo.
Življenjski cikel niti v Javi
Življenjski cikel niti:
Kot je prikazano na zgornjem diagramu, obstajajo različne stopnje življenjskega cikla niti:
- Novo
- Teče
- Tek
- Čakanje
- Mrtev
- Novo: V tej fazi se nit ustvari z uporabo razreda "Thread class". V tem stanju ostane, dokler program ne zažene niti. Znano je tudi kot rojena nit.
- Izvedljivo: Na tej strani se primerek niti prikliče z začetno metodo. Nadzor niti je dodeljen načrtovalcu, da dokonča izvedbo. Od načrtovalca je odvisno, ali naj nit zažene.
- Izvajanje: Ko se nit začne izvajati, se stanje spremeni v stanje "teče". Načrtovalnik izbere eno nit iz področja niti in se začne izvajati v aplikaciji.
- Čakanje: To je stanje, ko mora nit čakati. Ker se v aplikaciji izvaja več niti, obstaja potreba po sinhronizaciji med nitmi. Zato mora ena nit počakati, dokler se druga nit ne izvede. Zato se to stanje imenuje stanje čakanja.
- Dead: To je stanje, ko se nit konča. Nit je v delujočem stanju in takoj po zaključku obdelave je v "mrtvem stanju".
Nekatere najpogosteje uporabljene metode za niti so:
Metoda | Opis |
---|---|
začetek () | Ta metoda začne izvajanje niti in JVM pokliče metodo run () v niti. |
Spanje (int milisekunde) | Ta metoda naredi nit v stanju mirovanja, zato se bo izvedba niti zaustavila za zagotovljene milisekunde, nato pa se nit spet začne izvajati. To pomaga pri sinhronizaciji niti. |
getName () | Vrne ime niti. |
setPriority (int newpriority) | Spremeni prednost niti. |
donos () | To povzroči izvajanje trenutne niti na zaustavitvi in drugih niti. |
Primer: V tem primeru bomo ustvarili nit in raziskali vgrajene metode, ki so na voljo za niti.
demotest paketa;javni razred thread_example1 izvaja Runnable {@Overridejavni void run () {}public static void main (String [] args) {Nit guruthread1 = nova nit ();guruthread1.start ();poskusite {guruthread1.spaj (1000);} catch (InterruptedException e) {// TODO Samodejno ustvarjen blok ulovae.printStackTrace ();}guruthread1.setPriority (1);int gurupriority = guruthread1.getPriority ();System.out.println (gurupriority);System.out.println ("Nit se izvaja");}}
Pojasnilo kode:
- Vrstica kode 2: Ustvarjamo razred "thread_Example1", ki implementira vmesnik Runnable (implementiral bi ga moral kateri koli razred, katerega primerki naj bi bili izvedeni v niti).
- Vrstica kode 4: razveljavi način izvajanja vmesnika, ki ga je mogoče voditi, saj je obvezno to metodo preglasiti
- 6. vrstica kode: Tu smo opredelili glavno metodo, s katero bomo začeli izvajati nit.
- 7. vrstica kode: Tu ustvarjamo novo ime niti kot "guruthread1", tako da ustvarimo nov razred niti.
- Vrstica kode 8: uporabili bomo metodo »start« niti z uporabo primerka »guruthread1«. Tu se bo nit začela izvajati.
- Vrstica kode 10: Tu uporabljamo metodo "spanja" niti z uporabo primerka "guruthread1". Tako bo nit spala 1000 milisekund.
- Koda 9-14: Tu smo v blok try catch uvrstili način spanja, saj se pojavi preverjena izjema, tj.
- Vrstica kode 15: Tu nastavimo prioriteto niti na 1, ne glede na to, katera prednost je bila
- Vrstica kode 16: Tu dobimo prednost niti z uporabo getPriority ()
- Vrstica kode 17: Tu tiskamo vrednost, pridobljeno iz getPriority
- Vrstica kode 18: Tu pišemo besedilo, v katerem se nit izvaja.
Ko zaženete zgornjo kodo, dobite naslednji izhod:
Izhod:
5 je prednost teme, Thread Running pa besedilo, ki je rezultat naše kode.
Sinhronizacija niti Java
Pri večnitnosti obstaja asinhrono vedenje programov. Če ena nit piše nekatere podatke, druga nit, ki hkrati bere podatke, pa lahko povzroči neskladnost v aplikaciji.
Kadar je treba do virov v skupni rabi dostopati z dvema ali več nitmi, se uporabi pristop sinhronizacije.
Java je zagotovila sinhronizirane metode za izvajanje sinhroniziranega vedenja.
Pri tem pristopu, ko nit doseže znotraj sinhroniziranega bloka, nobena druga nit ne more poklicati te metode za isti predmet. Vse niti morajo počakati, da ta nit dokonča sinhronizirani blok in izstopi iz njega.
Na ta način sinhronizacija pomaga v večnitni aplikaciji. Ena nit mora počakati, da druga nit zaključi svoje izvajanje šele takrat, ko so druge niti dovoljene za izvajanje.
Zapišemo ga lahko v naslednji obliki:
Sinhronizirano (objekt){// Blok stavkov, ki se sinhronizira}
Primer večnitnosti Java
V tem primeru bomo vzeli dve niti in poiskali imena niti.
Primer1:
GuruThread1.javademotest paketa;javni razred GuruThread1 izvaja Runnable {/ *** @param args* /public static void main (String [] args) {Thread guruThread1 = nova nit ("Guru1");Thread guruThread2 = nova nit ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("Imena niti so naslednja:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@Overridejavni void run () {}}
Pojasnilo kode:
- Vrstica kode 3: Vzeli smo razred "GuruThread1", ki implementira Runnable (izvajati ga mora vsak razred, katerega primerki naj bi bili izvedeni v niti).
- Vrstica kode 8: To je glavna metoda predavanja
- Vrstica kode 9: Tu ustvarjamo primer razreda Thread in ustvarjamo primerek z imenom "guruThread1" ter ustvarjamo nit.
- Vrstica kode 10: Tu ustvarjamo primer razreda Thread in ustvarjamo primerek z imenom "guruThread2" ter ustvarjamo nit.
- Koda 11: Začenjamo nit, tj. GuruThread1.
- Vrstica kode 12: Začenjamo nit, tj. GuruThread2.
- Kodijska vrstica 13: Besedilo se prikaže kot "Imena niti so naslednja:"
- Vrstica kode 14: Pridobivanje imena niti 1 z uporabo metode getName () razreda niti.
- Vrstica kode 15: Pridobivanje imena niti 2 z uporabo metode getName () razreda niti.
Ko zaženete zgornjo kodo, dobite naslednji izhod:
Izhod:
Imena niti so tukaj prikazana kot
- Guru1
- Guru2
2. primer:
V tem primeru bomo izvedeli več o metodah run () in start () metode, ki jo je mogoče zagnati, in ustvarili dve niti tega razreda ter jih ustrezno zagnali.
Prav tako obiskujemo dva predavanja,
- Tisti, ki bo implementiral vmesnik, ki ga je mogoče voditi, in
- Druga, ki bo imela glavno metodo in jo bo ustrezno izvedla.
demotest paketa;javni razred GuruThread2 {public static void main (String [] args) {// TODO Samodejno ustvarjena škrbina metodeGuruThread3 threadguru1 = novi GuruThread3 ("guru1");threadguru1.start ();GuruThread3 threadguru2 = nov GuruThread3 ("guru2");threadguru2.start ();}}razred GuruThread3 izvaja Runnable {Nit guruthread;guruname zasebnega niza;GuruThread3 (ime niza) {guruname = ime;}@Overridejavni void run () {System.out.println ("Nit se izvaja" + guruname);za (int i = 0; i <4; i ++) {System.out.println (i);System.out.println (guruname);poskusite {Navoj.spanje (1000);} catch (InterruptedException e) {System.out.println ("Nit je prekinjen");}}}javni void start () {System.out.println ("Nit se je začel");če (guruthread == null) {guruthread = nova nit (to, guruname);guruthread.start ();}}}
Pojasnilo kode:
- 2. vrstica kode: Tu gremo v razred "GuruThread2", v katerem bo glavna metoda.
- Vrstica kode 4: Tukaj je glavna metoda predavanja.
- Vrstica kode 6-7: Tu ustvarjamo primerek razreda GuruThread3 (ki je ustvarjen v spodnjih vrsticah kode) kot "threadguru1" in začenjamo nit.
- Vrstica kode 8-9: Tu ustvarjamo še en primerek razreda GuruThread3 (ki je ustvarjen v spodnjih vrsticah kode) kot "threadguru2" in začenjamo nit.
- Vrstica kode 11: Tu ustvarjamo razred "GuruThread3", ki izvaja vmesnik, ki ga je mogoče zagnati (implementirati ga mora vsak razred, katerega primerki naj bi bili izvedeni v niti).
- Vrstica kode 13-14: vzamemo dve spremenljivki razreda, od katerih je ena v razredu niti in druga v nizu.
- Vrstica kode 15-18: preglasimo konstruktor GuruThread3, ki kot vrsto niza (ki je ime niti) vzame en argument, ki je dodeljen spremenljivki razreda guruname in je zato ime niti shranjeno.
- Vrstica kode 20: Tu preglasimo metodo run () vmesnika, ki ga je mogoče zagnati.
- Vrstica kode 21: Ime niti izpišemo s pomočjo stavka println.
- Vrstica kode 22-31: Tu uporabljamo zanko for s števcem, inicializiranim na 0, in ne sme biti manj kot 4 (lahko vzamemo poljubno število, zato bo zanka tekla 4-krat) in povečujemo števec. Tiskamo ime niti in tako omogočimo, da nit preklopi 1000 milisekund v bloku try-catch, saj je način spanja sprožil preverjeno izjemo.
- Vrstica kode 33: Tu prevladujemo nad načinom zagona vodljivega vmesnika.
- Kodijska vrstica 35: Izpišemo besedilo "Nit se je začel".
- Vrstica kode 36-40: Tu uporabljamo pogoj if, da preverimo, ali ima spremenljivka razreda guruthread vrednost v sebi ali ne. Če je nič, potem ustvarjamo primerek z uporabo razreda niti, ki za parameter vzame ime (vrednost, ki je bila dodeljena v konstruktorju). Nato se nit začne z uporabo metode start ().
Ko zaženete zgornjo kodo, dobite naslednji izhod:
Izhod :
Torej obstajata dve niti, dvakrat dobimo sporočilo "Nit se je začel".
Imena niti dobimo, kot smo jih dali.
Gre v zanko for, kjer tiskamo števec in ime niti, števec pa se začne z 0.
Zanka se izvede trikrat, vmes pa nit preklopi 1000 milisekund.
Zato najprej dobimo guru1, nato guru2, nato spet guru2, ker nit tukaj spi 1000 milisekund, nato pa naslednji guru1 in spet guru1, nit spi 1000 milisekund, tako da dobimo guru2 in nato guru1.
Povzetek :
V tej vadnici smo videli večnitne programe v Javi in kako uporabljati enojne in večnitne niti.
- Pri večnitnem načinu uporabniki niso blokirani, saj so niti neodvisne in lahko izvajajo več operacij hkrati
- Različne stopnje življenjskega cikla niti so,
- Novo
- Teče
- Tek
- Čakanje
- Mrtev
- Spoznali smo tudi sinhronizacijo med nitmi, ki pomagajo, da aplikacija deluje nemoteno.
- Večnitnost olajša veliko več aplikacijskih nalog.