Multitråda in Java
Alla program kan ha flera processer (instanser). Var och en av dessa processer kan tilldelas antingen som en enda tråd eller flera trådar. Vi kommer att se i denna handledning hur man utför flera uppgifter samtidigt och även lära oss mer om trådar och synkronisering mellan trådar.
Vad är Single Thread?
En enda tråd in Java är i grunden en lätt och den minsta bearbetningsenheten. Java använder trådar genom att använda en "Trådklass". Det finns två typer av tråd - användartråd och demontråd (demontrådar används när vi vill rengöra applikationen och används i bakgrunden). När en applikation först startar skapas en användartråd. Lägg upp det, vi kan skapa många användartrådar och demontrådar.
Exempel på en tråd:
package demotest; public class GuruThread { public static void main(String[] args) { System.out.println("Single Thread"); } }
Fördelar med enkel tråd:
- Minskar overhead i applikationen när enstaka trådar körs i systemet
- Dessutom minskar det underhållskostnaden för applikationen.
Vad är Multithreading i Java?
multitrådning in Java är en process där två eller flera trådar körs samtidigt för maximalt utnyttjande av CPU. Flertrådade applikationer kör två eller flera trådar samtidigt. Därför är det också känt som Concurrency in Java. Varje tråd löper parallellt med varandra. Flera trådar allokerar inte separat minnesområde, därför sparar de minne. Dessutom tar kontextväxling mellan trådar mindre tid.
Exempel på multitråd:
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() { } }
Fördelar med multithread:
- Användarna blockeras inte eftersom trådarna är oberoende och vi kan utföra flera operationer ibland
- Som sådana är trådarna oberoende, de andra trådarna kommer inte att påverkas om en tråd möter ett undantag.
Tråda livscykel in Java
Livscykeln för en tråd:
Det finns olika stadier av trådens livscykel som visas i diagrammet ovan:
- Nytt
- Körbar
- Springa
- väntar
- Död
- Ny: I denna fas skapas tråden med klassen "Trådklass". Den förblir i detta tillstånd till programmet startar tråden. Det är också känt som född tråd.
- Kan köras: På den här sidan anropas instansen av tråden med en startmetod. Trådkontrollen ges till schemaläggaren för att avsluta exekveringen. Det beror på schemaläggaren om tråden ska köras.
- Löpning: När tråden börjar köras ändras tillståndet till tillståndet "kör". Schemaläggaren väljer en tråd från trådpoolen och den börjar köras i applikationen.
- Väntar: Detta är tillståndet när en tråd måste vänta. Eftersom det körs flera trådar i applikationen finns det ett behov av synkronisering mellan trådarna. Därför måste en tråd vänta tills den andra tråden körs. Därför kallas detta tillstånd för väntande tillstånd.
- Död: Detta är tillståndet när tråden avslutas. Tråden är i körläge och så snart den avslutats bearbetningen är den i "dött tillstånd".
Metoder för att multitråda in Java
Några av de vanligaste metoderna för trådar är:Metod | Description |
---|---|
Start() | Denna metod startar exekveringen av tråden och JVM anropar metoden run() på tråden. |
Sömn (int millisekunder) | Den här metoden gör att tråden sover, så att trådens körning pausas i millisekunder och efter det börjar tråden köras igen. Detta hjälper till att synkronisera trådarna. |
hämta namn () | Det returnerar namnet på tråden. |
setPriority(int newpriority) | Det ändrar trådens prioritet. |
avkastning () | Det gör att nuvarande tråd stannar och andra trådar körs. |
Exempelvis: I detta multithreading-program i Java Vi ska till exempel skapa en tråd och utforska inbyggda metoder som är tillgängliga för trådar.
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"); } }
Förklaring av koden:
- Kodrad 2: Vi skapar en klass "thread_Example1" som implementerar Runnable-gränssnittet (det bör implementeras av alla klasser vars instanser är avsedda att exekveras av tråden.)
- Kodrad 4: Det åsidosätter körningsmetoden för det körbara gränssnittet eftersom det är obligatoriskt att åsidosätta den metoden
- Kodrad 6: Här har vi definierat huvudmetoden där vi kommer att starta exekveringen av tråden.
- Kodrad 7: Här skapar vi ett nytt trådnamn som "guruthread1" genom att instansiera en ny trådklass.
- Kodrad 8: vi kommer att använda "start" metoden för tråden med "guruthread1" instans. Här kommer tråden att börja köras.
- Kodrad 10: Här använder vi "sömn" -metoden för tråden med "guruthread1" -instans. Därför kommer tråden att vila i 1000 millisekunder.
- Kod 9-14: Här har vi satt sömnmetoden i try catch-blocket då det finns ett markerat undantag som inträffar dvs. Avbrutet undantag.
- Kodrad 15: Här sätter vi trådens prioritet till 1 från vilken prioritet den än var
- Kodrad 16: Här får vi prioritet för tråden med getPriority()
- Kodrad 17: Här skriver vi ut värdet som hämtats från getPriority
- Kodrad 18: Här skriver vi en text som tråden är igång.
När du kör ovanstående kod får du följande utdata:
Produktion:
5 är trådprioriteten och trådkörning är texten som är resultatet av vår kod.
Java Tråd Synchronisering
I multithreading finns det asynkrona beteendet hos programmen. Om en tråd skriver vissa data och en annan tråd som läser data samtidigt, kan det skapa inkonsekvens i applikationen. När det finns ett behov av att komma åt de delade resurserna med två eller flera trådar, används synkroniseringsmetod. Java har tillhandahållit synkroniserade metoder för att implementera synkroniserat beteende.
I detta tillvägagångssätt, när tråden når inuti det synkroniserade blocket, kan ingen annan tråd anropa den metoden på samma objekt. Alla trådar måste vänta tills den tråden avslutar det synkroniserade blocket och kommer ut ur det. På så sätt hjälper synkroniseringen till i en flertrådad applikation. En tråd måste vänta tills den andra tråden avslutar sin exekvering, bara då är de andra trådarna tillåtna för exekvering.
Det kan skrivas i följande form:
Synchronized(object) { //Block of statements to be synchronized }
Multitråda in Java Exempel program
I denna multithreading Java till exempel tar vi två trådar och hämtar namnen på tråden.
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() { } }
Förklaring av koden:
- Kodrad 3: Vi har tagit en klass "GuruThread1" som implementerar Runnable (den bör implementeras av alla klasser vars instanser är avsedda att exekveras av tråden.)
- Kodrad 8: Detta är klassens huvudsakliga metod
- Kodrad 9: Här instansierar vi klassen Thread och skapar en instans som heter "guruThread1" och skapar en tråd.
- Kodrad 10: Här instansierar vi klassen Thread och skapar en instans som heter "guruThread2" och skapar en tråd.
- Kodrad 11: Vi startar tråden dvs guruThread1.
- Kodrad 12: Vi startar tråden dvs guruThread2.
- Kodrad 13: Skriver ut texten som "Trådnamn är följande:"
- Kodrad 14: Hämta namnet på tråd 1 med metoden getName() för trådklassen.
- Kodrad 15: Hämta namnet på tråd 2 med metoden getName() för trådklassen.
När du kör ovanstående kod får du följande utdata:
Produktion:
Trådnamn matas ut här som
- Guru1
- Guru2
Exempel 2:
I denna multithreading in Java Till exempel kommer vi att lära oss om att åsidosätta metoderna run() och start() för ett körbart gränssnitt och skapa två trådar av den klassen och köra dem därefter.
Dessutom tar vi två klasser,
- En som kommer att implementera det körbara gränssnittet och
- En annan som kommer att ha huvudmetoden och köra därefter.
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(); } } }
Förklaring av koden:
- Kodrad 2: Här tar vi en klass "GuruThread2" som kommer att ha huvudmetoden i sig.
- Kodrad 4: Här tar vi en huvudmetod i klassen.
- Kodrad 6-7: Här skapar vi en instans av klassen GuruThread3 (som skapas på raderna nedan i koden) som "threadguru1" och vi startar tråden.
- Kodrad 8-9: Här skapar vi en annan instans av klassen GuruThread3 (som skapas i nedanstående rader i koden) som "threadguru2" och vi startar tråden.
- Kodrad 11: Här skapar vi en klass "GuruThread3" som implementerar det körbara gränssnittet (det bör implementeras av alla klasser vars instanser är avsedda att exekveras av tråden.)
- Kodrad 13-14: vi tar två klassvariabler från vilka den ena är av typen trådklass och den andra av strängklassen.
- Kodrad 15-18: vi åsidosätter GuruThread3-konstruktorn, som tar ett argument som strängtyp (vilket är trådens namn) som tilldelas klassvariabeln guruname och därför lagras namnet på tråden.
- Kodrad 20: Här åsidosätter vi run()-metoden för det körbara gränssnittet.
- Kodrad 21: Vi matar ut trådens namn med println-satsen.
- Kodrad 22-31: Här använder vi en for-slinga med räknaren initierad till 0, och den bör inte vara mindre än 4 (vi kan ta vilket tal som helst, därför kommer loopen att köras 4 gånger) och ökar räknaren. Vi skriver ut trådnamnet och gör även tråden i viloläge i 1000 millisekunder inom ett försöksfångstblock, eftersom vilometoden höjde ett markerat undantag.
- Kodrad 33: Här åsidosätter vi startmetoden för det körbara gränssnittet.
- Kodrad 35: Vi matar ut texten "Tråden startad".
- Kodrad 36-40: Här tar vi ett if-villkor för att kontrollera om klassvariabeln guruthread har ett värde i sig eller inte. Om den är null så skapar vi en instans med trådklassen som tar namnet som en parameter (värde som tilldelades i konstruktorn). Därefter startas tråden med metoden start().
När du kör ovanstående kod får du följande utdata:
Produktion:
Det finns två trådar, därför får vi två gånger meddelandet "Tråden har startat".
Vi får namnen på tråden som vi har skrivit ut dem.
Den går in i en slinga där vi skriver ut räknaren och trådnamnet och räknaren börjar med 0.
Slingan körs tre gånger och däremellan sover tråden i 1000 millisekunder.
Därför får vi först guru1 sedan guru2 och sedan igen guru2 eftersom tråden sover här i 1000 millisekunder och sedan nästa guru1 och igen guru1, tråd sover i 1000 millisekunder, så vi får guru2 och sedan guru1.
Sammanfattning
I den här handledningen såg vi flertrådade applikationer i Java och hur man använder enkel- och multitråd i Java.
- Förklara multithreading Java: i multithreading blockeras inte användare eftersom trådar är oberoende och kan utföra flera operationer samtidigt
- Olika stadier av trådens livscykel är,
- Nytt
- Körbar
- Springa
- väntar
- Död
- Vi lärde oss också om synkronisering mellan trådar, vilket hjälper applikationen att fungera smidigt.
- Flertrådad programmering in Java gör många fler applikationsuppgifter enklare.