Višenitnost u Java
Svaka aplikacija može imati više procesa (instanci). Svaki od ovih procesa može se dodijeliti kao jedna niti kao više niti. U ovom ćemo vodiču vidjeti kako izvršiti više zadataka u isto vrijeme i također naučiti više o nitima i sinkronizaciji između niti.
Što je jedna nit?
Jedna nit unutra Java je u osnovi lagana i najmanja jedinica za obradu. Java koristi niti pomoću "klase niti". Postoje dvije vrste niti – korisnička nit i demonska nit (daemon niti se koriste kada želimo očistiti aplikaciju i koriste se u pozadini). Kada se aplikacija prvi put pokrene, kreira se korisnička nit. Nakon toga, možemo stvoriti mnoge korisničke niti i demonske niti.
Primjer jedne niti:
package demotest; public class GuruThread { public static void main(String[] args) { System.out.println("Single Thread"); } }
Prednosti jedne niti:
- Smanjuje opterećenje u aplikaciji jer se u sustavu izvršava jedna nit
- Također, smanjuje troškove održavanja aplikacije.
U čemu je Multithreading Java?
Višenitnost in Java je proces izvršavanja dvije ili više niti istovremeno radi maksimalnog iskorištenja CPU-a. Višenitne aplikacije izvode dvije ili više niti koje se izvode istovremeno. Stoga je također poznat kao Concurrency in Java. Svaka nit ide paralelno jedna s drugom. Višestruke niti ne dodjeljuju zasebno memorijsko područje, stoga štede memoriju. Također, prebacivanje konteksta između niti traje manje vremena.
Primjer više niti:
package demotest; public class GuruThread1 implements Runnable { public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
Prednosti višenitnosti:
- Korisnici nisu blokirani jer su niti neovisne i možemo izvoditi više operacija u isto vrijeme
- Kao takve, niti su neovisne, druge niti neće biti pogođene ako jedna nit naiđe na iznimku.
Životni ciklus niti u Java
Životni ciklus niti:
Postoje različite faze životnog ciklusa niti kao što je prikazano na gornjem dijagramu:
- Novo
- Izvodljivo
- Trčanje
- čekanje
- Mrtav
- Novo: U ovoj fazi, nit se kreira koristeći klasu “Thread class”. Ona ostaje u ovom stanju do programa počinje nit. Također je poznata kao rođena nit.
- Pokretljivo: Na ovoj se stranici instanca niti poziva metodom pokretanja. Kontrola niti se daje planeru da završi izvršenje. Ovisi o planeru hoće li pokrenuti nit.
- Trčanje: Kada se nit počne izvršavati, stanje se mijenja u stanje "izvršenje". Planer odabire jednu nit iz skupa niti i počinje se izvršavati u aplikaciji.
- Čekanje: Ovo je stanje kada nit mora čekati. Budući da se u aplikaciji izvodi više niti, postoji potreba za sinkronizacijom između niti. Dakle, jedna nit mora čekati dok se druga nit ne izvrši. Stoga se ovo stanje naziva stanjem čekanja.
- Mrtav: Ovo je stanje kada je nit prekinuta. Nit je u stanju pokretanja i čim završi obradu, nalazi se u "mrtvom stanju".
Metode višenitnosti u Java
Neke od najčešće korištenih metoda za niti su:način | Description |
---|---|
početak() | Ova metoda pokreće izvođenje dretve i JVM poziva metodu run() na niti. |
Mirovanje (int milisekundi) | Ova metoda čini nit mirovanjem pa će se izvođenje niti zaustaviti na predviđene milisekunde i nakon toga se nit ponovno počinje izvršavati. Ovo pomaže u sinkronizaciji niti. |
getName () | Vraća naziv niti. |
setPriority(int newpriority) | Mijenja prioritet niti. |
prinos () | Uzrokuje zaustavljanje trenutne niti i izvršavanje drugih niti. |
Primjer: U ovom višenitnom programu u Java Na primjer, stvorit ćemo nit i istražiti ugrađene metode dostupne za niti.
package demotest; public class thread_example1 implements Runnable { @Override public void run() { } public static void main(String[] args) { Thread guruthread1 = new Thread(); guruthread1.start(); try { guruthread1.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } guruthread1.setPriority(1); int gurupriority = guruthread1.getPriority(); System.out.println(gurupriority); System.out.println("Thread Running"); } }
Objašnjenje koda:
- Redak koda 2: Stvaramo klasu “thread_Example1” koja implementira Runnable sučelje (trebala bi ga implementirati bilo koja klasa čije instance namjerava izvršiti nit.)
- Redak koda 4: Ona nadjačava metodu pokretanja sučelja koje se može pokrenuti jer je obavezno nadjačati tu metodu
- Redak koda 6: Ovdje smo definirali glavnu metodu u kojoj ćemo pokrenuti izvođenje dretve.
- Redak koda 7: Ovdje stvaramo novi naziv niti kao "guruthread1" instanciranjem nove klase niti.
- Redak koda 8: koristit ćemo metodu “start” niti koristeći instancu “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.
- Kod 9-14: Ovdje smo stavili metodu mirovanja u blok pokušaja hvatanja jer postoji provjerena iznimka koja se javlja, tj. prekinuta iznimka.
- Redak koda 15: Ovdje postavljamo prioritet niti na 1 od bilo kojeg prioriteta
- Redak koda 16: Ovdje dobivamo prioritet niti koristeći getPriority()
- Redak koda 17: Ovdje ispisujemo vrijednost dohvaćenu iz getPriority
- Redak koda 18: Ovdje pišemo tekst koji se pokreće.
Kada izvršite gornji kod, dobit ćete sljedeći izlaz:
Izlaz:
5 je Thread prioritet, a Thread Running je tekst koji je izlaz našeg koda.
Java Nit Synchroniziranje
Kod višenitnosti postoji asinkrono ponašanje programa. Ako jedna nit zapisuje neke podatke, a druga nit koja čita podatke u isto vrijeme, može doći do nedosljednosti u aplikaciji. Kada postoji potreba za pristupom zajedničkim resursima putem dvije ili više niti, tada se koristi pristup sinkronizacije. Java je osigurao sinkronizirane metode za implementaciju sinkroniziranog ponašanja.
U ovom pristupu, kada nit dospije unutar sinkroniziranog bloka, nijedna druga nit ne može pozvati tu metodu na istom objektu. Sve niti moraju č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 ne završi svoje izvršenje tek tada je ostalim dretvama dopušteno izvršenje.
Može se napisati u sljedećem obliku:
Synchronized(object) { //Block of statements to be synchronized }
Višenitnost u Java Primjeri programa
U ovoj višenitnosti Java Na primjer, uzet ćemo dvije niti i dohvatiti imena niti.
Example1:
GuruThread1.java package demotest; public class GuruThread1 implements Runnable{ /** * @param args */ public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
Objašnjenje koda:
- Redak koda 3: Uzeli smo klasu "GuruThread1" koja implementira Runnable (trebala bi je implementirati bilo koja klasa čije instance namjerava izvršavati nit.)
- Redak koda 8: Ovo je glavna metoda klase
- Redak koda 9: Ovdje instanciramo klasu Thread i stvaramo instancu pod nazivom "guruThread1" i stvaramo nit.
- Redak koda 10: Ovdje instanciramo klasu Thread i stvaramo instancu pod nazivom "guruThread2" i stvaramo nit.
- Redak koda 11: Pokrećemo nit tj. guruThread1.
- Redak koda 12: Pokrećemo nit tj. guruThread2.
- Redak koda 13: Ispis teksta kao "Nazivi niti su sljedeći:"
- Redak koda 14: Dobivanje naziva niti 1 pomoću metode getName() klase niti.
- Redak koda 15: Dobivanje naziva niti 2 pomoću metode getName() klase niti.
Kada izvršite gornji kod, dobit ćete sljedeći izlaz:
Izlaz:
Ovdje se ispisuju nazivi niti kao
- Guru1
- Guru2
Primjer 2:
U ovoj multithreading in Java na primjer, naučit ćemo o nadjačavanju metoda run() i start() metode sučelja koje se može izvoditi i stvoriti dvije niti te klase i pokrenuti ih u skladu s tim.
Također, pohađamo dva razreda,
- Onaj koji će implementirati sučelje koje se može izvoditi i
- Još jedan koji će imati glavnu metodu i izvršavati se u skladu s tim.
package demotest; public class GuruThread2 { public static void main(String[] args) { // TODO Auto-generated method stub GuruThread3 threadguru1 = new GuruThread3("guru1"); threadguru1.start(); GuruThread3 threadguru2 = new GuruThread3("guru2"); threadguru2.start(); } } class GuruThread3 implements Runnable { Thread guruthread; private String guruname; GuruThread3(String name) { guruname = name; } @Override public void run() { System.out.println("Thread running" + guruname); for (int i = 0; i < 4; i++) { System.out.println(i); System.out.println(guruname); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Thread has been interrupted"); } } } public void start() { System.out.println("Thread started"); if (guruthread == null) { guruthread = new Thread(this, guruname); guruthread.start(); } } }
Objašnjenje koda:
- Redak koda 2: Ovdje uzimamo klasu "GuruThread2" koja će imati glavnu metodu u sebi.
- Redak koda 4: Ovdje uzimamo glavnu metodu klase.
- Redak koda 6-7: Ovdje stvaramo instancu klase GuruThread3 (koja je stvorena u donjim redovima koda) kao "threadguru1" i pokrećemo nit.
- Redak koda 8-9: Ovdje stvaramo još jednu instancu klase GuruThread3 (koja je stvorena u donjim redovima koda) kao "threadguru2" i pokrećemo nit.
- Redak koda 11: Ovdje stvaramo klasu "GuruThread3" koja implementira sučelje koje se može izvoditi (trebala bi ga implementirati bilo koja klasa čije instance namjerava izvršavati nit.)
- Redak koda 13-14: uzimamo dvije varijable klase od kojih je jedna klase niti, a druga klase niza.
- Redak koda 15-18: mi nadjačavamo konstruktor GuruThread3, koji uzima jedan argument kao tip niza (koji je naziv niti) koji se dodjeljuje varijabli klase guruname i stoga se pohranjuje naziv niti.
- Redak koda 20: Ovdje nadjačavamo metodu run() sučelja koje se može izvoditi.
- Redak koda 21: Ispisujemo naziv niti pomoću izjave println.
- Redak koda 22-31: Ovdje koristimo for petlju s brojačem inicijaliziranim na 0, a ne smije biti manji od 4 (možemo uzeti bilo koji broj stoga će se ovdje petlja pokrenuti 4 puta) i povećavamo brojač. Ispisujemo naziv niti i također stavljamo nit u stanje mirovanja na 1000 milisekundi unutar bloka try-catch jer je metoda mirovanja pokrenula provjerenu iznimku.
- Redak koda 33: Ovdje nadjačavamo metodu pokretanja sučelja koje se može pokrenuti.
- Redak koda 35: Ispisujemo tekst "Thread started".
- Redak koda 36-40: Ovdje uzimamo if uvjet da provjerimo ima li varijabla klase guruthread vrijednost u sebi ili ne. Ako je null, tada stvaramo instancu pomoću klase niti koja uzima naziv kao parametar (vrijednost za koju je dodijeljena u konstruktoru). Nakon toga se nit pokreće metodom start().
Kada izvršite gornji kod, dobit ćete sljedeći izlaz:
Izlaz:
Postoje dvije niti, dakle, dobivamo dva puta poruku "Thread started".
Dobivamo nazive niti onako kako smo ih ispisali.
Ide u for petlju gdje ispisujemo brojač i naziv niti, a brojač počinje s 0.
Petlja se izvodi tri puta, a između nit ostaje u stanju mirovanja 1000 milisekundi.
Dakle, prvo dobivamo guru1 pa 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 pa guru1.
rezime
U ovom vodiču vidjeli smo višenitne aplikacije Java i kako koristiti jednu i više niti u Java.
- Objasnite višenitnost u Java: u multithreadingu, korisnici nisu blokirani jer su niti neovisne i mogu izvoditi više operacija u isto vrijeme
- Različite faze životnog ciklusa niti su,
- Novo
- Izvodljivo
- Trčanje
- čekanje
- Mrtav
- Također smo naučili o sinkronizacija između niti, što pomaže glatkom radu aplikacije.
- Višenitno programiranje u Java olakšava mnogo više aplikacijskih zadataka.