Multithreading u Java Vodič s primjerima

Sadržaj:

Anonim

Svaka aplikacija može imati više procesa (instanci). Svaki od ovog procesa može se dodijeliti ili kao jedna nit ili kao više niti. U ovom ćemo uputstvu vidjeti kako istodobno izvoditi više zadataka, a također ćemo naučiti više o nitima i sinkronizaciji između niti.

U ovom uputstvu naučit ćemo:

  • Što je pojedinačna nit
  • Što je Multithreading u Javi?
  • Životni ciklus niti u Javi
  • Sinkronizacija niti Java
  • Primjer višenamenskog Java-a

Što je pojedinačna nit?

Jedna nit je u osnovi lagana i najmanja jedinica obrade. Java koristi niti koristeći "klasu niti".

Postoje dvije vrste niti - korisnička nit i demon demon (daemon niti se koriste kada želimo očistiti aplikaciju i koriste se u pozadini).

Kada aplikacija prvi put započne, kreira se korisnička nit. Objavivši to, možemo stvoriti mnogo korisničkih niti i demonskih niti.

Primjer jedne niti:

demotest paketa;javna klasa GuruThread{javna statička void glavna (String [] args) {System.out.println ("Jedna nit");}}

Prednosti jednog navoja:

  • Smanjuje općenite troškove u aplikaciji dok se jedna nit izvršava u sustavu
  • Također, smanjuje troškove održavanja aplikacije.

Što je Multithreading u Javi?

MULTITHREADING u Javi postupak je izvršavanja dviju ili više niti istovremeno do maksimalne iskorištenosti CPU-a. Višenitne aplikacije izvršavaju istovremeno dvije ili više niti. Stoga je u Javi poznat i kao istodobnost. Svaka nit ide paralelno jedna s drugom. Višestruke niti ne izdvajaju odvojeno memorijsko područje, stoga štede memoriju. Također, prebacivanje konteksta između niti traje manje vremena.

Primjer više niti:

demotest paketa;javna klasa GuruThread1 implementira Runnable{javna statička void glavna (String [] args) {Thread guruThread1 = nova nit ("Guru1");Thread guruThread2 = nova nit ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("Imena niti su sljedeća:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@Preuzmijavni void run () {}}

Prednosti multithreada:

  • Korisnici nisu blokirani jer su niti nezavisne i možemo istodobno izvoditi više operacija
  • Kako su takve niti neovisne, ostale niti neće biti pogođene ako jedna nit zadovolji iznimku.

Životni ciklus niti u Javi

Životni ciklus niti:

Postoje različite faze životnog ciklusa konca kao što je prikazano na gornjem dijagramu:

  1. Novi
  2. Izvodljivo
  3. Trčanje
  4. Čekanje
  5. Mrtav
  1. Novo: U ovoj fazi nit se stvara pomoću klase "Klasa niti". Ona ostaje u tom stanju dok program ne pokrene nit. Također je poznat kao rođena nit.
  2. Izvodljivo: Na ovoj se stranici instanca niti poziva metodom pokretanja. Kontrola niti daje se planeru da završi izvršenje. Ovisno o planeru, hoće li pokrenuti nit.
  3. Pokretanje: Kada se nit počne izvršavati, tada se stanje mijenja u stanje "pokrenuto". Planer odabire jednu nit iz spremišta niti i ona se počinje izvršavati u aplikaciji.
  4. Čekanje: Ovo je stanje kada nit mora čekati. Kako se u aplikaciji izvodi više niti, postoji potreba za sinkronizacijom između niti. Stoga jedna nit mora pričekati dok se druga nit ne izvrši. Stoga se ovo stanje naziva stanjem čekanja.
  5. Mrtvo: Ovo je stanje kada se nit prekida. Nit je u aktivnom stanju i čim završi s obradom u "je mrtvom stanju".

Neke od najčešće korištenih metoda za niti su:

Metoda Opis
početak() Ova metoda započinje izvršavanje niti, a JVM poziva metodu run () na niti.
Spavanje (int milisekunde) Ova metoda čini nit niti uspavanom, stoga će se izvršavanje niti zaustaviti na predviđene milisekunde, a nakon toga nit se počinje izvršavati. Ovo pomaže u sinkronizaciji niti.
getName () Vraća ime niti.
setPriority (int newpriority) Mijenja prioritet niti.
prinos () Uzrokuje izvršavanje trenutne niti na zaustavljanju i ostalih niti.

Primjer: U ovom ćemo primjeru stvoriti nit i istražiti ugrađene metode dostupne za niti.

demotest paketa;javna klasa thread_example1 implementira Runnable {@Preuzmijavni void run () {}javna statička void glavna (String [] args) {Tema guruthread1 = nova nit ();guruthread1.start ();probaj {guruthread1.sleep (1000);} catch (InterruptedException e) {// TODO Automatski generirani blok ulovae.printStackTrace ();}guruthread1.setPriority (1);int gurupriority = guruthread1.getPriority ();System.out.println (guruprioritet);System.out.println ("Navoj pokrenut");}}

Objašnjenje koda:

  • Redak koda 2: Stvaramo klasu "thread_Example1" koja implementira Runnable sučelje (treba ga implementirati bilo koja klasa čije instance trebaju biti izvedene pomoću niti)
  • Redak koda 4: Nadjačava metodu pokretanja sučelja za izvođenje, jer je obavezno nadjačati tu metodu
  • 6. redak koda: Ovdje smo definirali glavnu metodu u kojoj ćemo započeti izvršavanje niti.
  • Redak koda 7: Ovdje stvaramo novo ime niti kao "guruthread1" instanciranjem nove klase niti.
  • Redak koda 8: koristit ćemo metodu "start" niti pomoću instance "guruthread1". Ovdje će se nit početi izvršavati.
  • Redak koda 10: Ovdje koristimo metodu "mirovanja" niti pomoću instance "guruthread1". Dakle, nit će spavati 1000 milisekundi.
  • Šifra 9-14: Ovdje smo metodi spavanja stavili blok try catch jer postoji provjerena iznimka koja se događa, tj. Prekinuta iznimka.
  • Redak koda 15: Ovdje postavljamo prioritet niti na 1 iz bilo kojeg prioriteta
  • Redak koda 16: Ovdje dobivamo prioritet niti pomoću getPriority ()
  • Linija koda 17: Ovdje ispisujemo vrijednost dohvaćenu iz getPriority
  • Redak 18: Ovdje pišemo tekst koji je pokrenut.

Kada izvršite gornji kod, dobit ćete sljedeći izlaz:

Izlaz:

5 je prioritet teme, a pokretanje niti je tekst koji je rezultat našeg koda.

Sinkronizacija niti Java

U multithreading-u postoji asinkrono ponašanje programa. Ako jedna nit zapisuje neke podatke, a druga nit koja istodobno čita podatke, to može stvoriti nedosljednost u aplikaciji.

Kada postoji potreba za pristup zajedničkim resursima pomoću dvije ili više niti, tada se koristi pristup sinkronizaciji.

Java je osigurala sinkronizirane metode za provedbu sinkroniziranog ponašanja.

U ovom pristupu, kada nit dosegne unutar sinkroniziranog bloka, tada niti jedna druga nit ne može pozvati tu metodu na istom objektu. Sve niti moraju pričekati dok ta nit završi sinkronizirani blok i izađe iz njega.

Na taj način sinkronizacija pomaže u višenitnoj aplikaciji. Jedna nit mora pričekati dok druga nit završi svoje izvršavanje tek tada su druge niti dopuštene za izvršenje.

Može se napisati u sljedećem obliku:

Sinkronizirano (objekt){// Blok izjava koje treba sinkronizirati}

Primjer višenamenskog Java-a

U ovom ćemo primjeru uzeti dvije niti i dohvatiti imena niti.

Primjer1:

GuruThread1.javademotest paketa;javna klasa GuruThread1 implementira Runnable {/ *** @param args* /javna statička void glavna (String [] args) {Thread guruThread1 = nova nit ("Guru1");Thread guruThread2 = nova nit ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("Imena niti su sljedeća:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@Preuzmijavni void run () {}}

Objašnjenje koda:

  • Redak koda 3: Zauzeli smo klasu "GuruThread1" koja implementira Runnable (nju bi trebala implementirati bilo koja klasa čije instance trebaju biti izvedene pomoću niti).
  • Kodni redak 8: Ovo je glavna metoda klase
  • Redak koda 9: Ovdje instanciramo klasu Thread i kreiramo instancu nazvanu "guruThread1" i stvaramo nit.
  • Redak koda 10: Ovdje uspostavljamo instancu klase Thread i stvaramo instancu nazvanu "guruThread2" i stvaramo nit.
  • Linija 11: Pokrećemo nit, tj. GuruThread1.
  • Redak koda 12: Pokrećemo nit, tj. GuruThread2.
  • Kodni redak 13: Izlaz teksta kao "Imena niti su sljedeća:"
  • Redak 14: Dobivanje imena niti 1 pomoću metode getName () klase niti.
  • Redak koda 15: Dobivanje imena niti 2 pomoću metode getName () klase niti.

Kada izvršite gornji kod, dobit ćete sljedeći izlaz:

Izlaz:

Imena niti se ovdje iznose kao

  • Guru1
  • Guru2

Primjer 2:

U ovom ćemo primjeru naučiti o nadjačavanju metoda run () i start () metode za pokretanje sučelja i stvoriti dvije niti te klase i pokrenuti ih u skladu s tim.

Također, pohađamo dva sata,

  • Onaj koji će implementirati izvodljivo sučelje i
  • Još jedan koji će imati glavnu metodu i izvršiti se u skladu s tim.
demotest paketa;javna klasa GuruThread2 {javna statička void glavna (String [] args) {// TODO Automatski generirani kvar metodeGuruThread3 threadguru1 = novi GuruThread3 ("guru1");threadguru1.start ();GuruThread3 threadguru2 = novi GuruThread3 ("guru2");threadguru2.start ();}}klasa GuruThread3 implementira Runnable {Navoj guruthread;privatni string guruname;GuruThread3 (naziv niza) {guruname = ime;}@Preuzmijavni void run () {System.out.println ("Nit pokrenut" + guruname);za (int i = 0; i <4; i ++) {System.out.println (i);System.out.println (guruname);probaj {Navoj.spavanje (1000);} catch (InterruptedException e) {System.out.println ("Nit je prekinut");}}}javni void start () {System.out.println ("Tema započeta");if (guruthread == null) {guruthread = nova nit (ovo, guruname);guruthread.start ();}}}

Objašnjenje koda:

  • Linija koda 2: Ovdje polazimo klasu "GuruThread2" u kojoj će biti glavna metoda.
  • Linija koda 4: Ovdje uzimamo glavnu metodu klase.
  • Redak koda 6-7: Ovdje stvaramo primjerak klase GuruThread3 (koja je stvorena u donjim redovima koda) kao "threadguru1" i započinjemo nit.
  • Redak koda 8-9: Ovdje stvaramo još jedan primjerak klase GuruThread3 (koja je stvorena u donjim redovima koda) kao "threadguru2" i započinjemo nit.
  • Linija koda 11: Ovdje stvaramo klasu "GuruThread3" koja implementira izvodljivo sučelje (treba ga implementirati bilo koja klasa čije instance trebaju biti izvedene pomoću niti).
  • Kodni redak 13-14: uzimamo dvije varijable klase od kojih je jedna klase tipa nit, a druga klase stringa.
  • Redak koda 15-18: nadjačavamo konstruktor GuruThread3, koji uzima jedan argument kao tip niza (koji je naziv niti) koji se dodjeljuje varijabli klase guruname i stoga se naziv niti pohranjuje.
  • Redak koda 20: Ovdje nadjačavamo metodu run () sučelja za izvođenje.
  • Linija 21: Izbacujemo ime niti pomoću naredbe println.
  • Linija koda 22-31: Ovdje koristimo for petlju s brojačem koji je inicijaliziran na 0, a on ne bi trebao biti manji od 4 (možemo uzeti bilo koji broj, pa će ovdje petlja raditi 4 puta) i povećavati brojač. Ispisujemo ime niti, a također omogućava da nit miruje 1000 milisekundi unutar bloka try-catch jer je metoda spavanja pokrenula provjerenu iznimku.
  • Linija koda 33: Ovdje prevladavamo metodu pokretanja sučelja za pokretanje.
  • Redak koda 35: Izbacujemo tekst "Tema započeta".
  • Kodni redak 36-40: Ovdje uzimamo uvjet if da provjerimo ima li varijabla klase guruthread vrijednost u sebi ili ne. Ako je null, tada stvaramo instancu koristeći klasu niti koja uzima ime kao parametar (vrijednost za koju je dodijeljena u konstruktoru). Nakon čega se nit pokreće metodom start ().

Kada izvršite gornji kod, dobit ćete sljedeći izlaz:

Izlaz :

Stoga postoje dvije niti, dva puta dobivamo poruku "Tema započeta".

Imena niti dobivamo onako kako smo ih iznijeli.

Ulazi u for petlju gdje ispisujemo brojač i naziv niti, a brojač započinje s 0.

Petlja se izvršava tri puta, a između niti se miruje 1000 milisekundi.

Dakle, prvo dobivamo guru1, zatim guru2, pa opet guru2, jer nit ovdje spava 1000 milisekundi, a zatim sljedeći guru1 i opet guru1, nit spava 1000 milisekundi, tako da dobivamo guru2, a zatim guru1.

Sažetak :

U ovom uputstvu vidjeli smo višenitne programe na Javi i kako koristiti pojedinačne i više niti.

  • U multithreading-u korisnici nisu blokirani jer su niti neovisne i mogu istodobno izvoditi više operacija
  • Razne faze životnog ciklusa niti su,
    • Novi
    • Izvodljivo
    • Trčanje
    • Čekanje
    • Mrtav
  • Također smo naučili o sinkronizaciji između niti, koje pomažu aplikaciji da nesmetano radi.
  • Multithreading olakšava mnogo više aplikacijskih zadataka.