Multithreading i Java Tutorial med exempel

Innehållsförteckning:

Anonim

Alla applikationer kan ha flera processer (instanser). Var och en av denna process 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 också lär mer om trådar och synkronisering mellan trådar.

I den här handledningen lär vi oss:

  • Vad är enkel tråd
  • Vad är Multithreading i Java?
  • Trådlivscykel i Java
  • Java-trådsynkronisering
  • Java Multithreading Exempel

Vad är enkel tråd?

En enda tråd ä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ådar - användartråd och daemontråd (daemontrådar används när vi vill rengöra applikationen och används i bakgrunden).

När en applikation först börjar skapas användartråd. Lägg upp det, vi kan skapa många användartrådar och daemontrådar.

Exempel på enstaka tråd:

paket demotest;offentlig klass GuruThread{public static void main (String [] args) {System.out.println ("Enkel tråd");}}

Fördelar med en tråd:

  • Minskar overhead i applikationen som en enda tråd körs i systemet
  • Det minskar också underhållskostnaden för applikationen.

Vad är Multithreading i Java?

MULTITREADING i Java är en process för att utföra två eller flera trådar samtidigt för att maximalt utnyttja CPU. Flertrådade applikationer kör två eller flera trådar som körs samtidigt. Därför är det också känt som Concurrency i Java. Varje tråd går parallellt med varandra. Mulitple-trådar tilldelar inte separat minnesområde, vilket sparar minne. Det tar också mindre tid att byta sammanhang mellan trådar.

Exempel på flertråd:

paket demotest;offentlig klass GuruThread1 implementerar Runnable{public static void main (String [] args) {Tråd guruThread1 = ny tråd ("Guru1");Tråd guruThread2 = ny tråd ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("Trådnamnen är följande:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@Åsidosättaoffentlig ogiltig körning () {}}

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 påverkas inte om en tråd uppfyller ett undantag.

Trådlivscykel i Java

Trådens livscykel:

Det finns olika stadier av trådens livscykel som visas i diagrammet ovan:

  1. Ny
  2. Körbar
  3. Löpning
  4. Väntar
  5. Död
  1. Nytt: I denna fas skapas tråden med hjälp av klass "Trådklass". Den förblir i detta tillstånd tills programmet startar tråden. Det är också känt som född tråd.
  2. Kan köras: På den här sidan anropas förekomsten av tråden med en startmetod. Trådkontrollen ges till schemaläggaren för att slutföra körningen. Det beror på schemaläggaren, om tråden ska köras.
  3. Running: När tråden börjar köras ändras tillståndet till "running" -tillstånd. Schemaläggaren väljer en tråd från trådpoolen och den körs i programmet.
  4. 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 som vänteläge.
  5. Död: Detta är tillståndet när tråden avslutas. Tråden är i pågående tillstånd och så snart den har slutförts är den i "död tillstånd".

Några av de vanliga metoderna för trådar är:

Metod Beskrivning
Start() Den här metoden startar körningen av tråden och JVM anropar metoden run () på tråden.
Sömn (int millisekunder) Denna metod gör att tråden sover, varför trådens körning kommer att pausa i millisekunder som tillhandahålls och efter det börjar tråden igen att köras. Detta hjälper till att synkronisera trådarna.
hämta namn() Den returnerar namnet på tråden.
setPriority (int newpriority) Det ändrar trådens prioritet.
avkastning () Det gör att aktuell tråd stoppas och andra trådar körs.

Exempel: I det här exemplet ska vi skapa en tråd och utforska inbyggda metoder som är tillgängliga för trådar.

paket demotest;public class thread_example1 implementerar Runnable {@Åsidosättaoffentlig ogiltig körning () {}public static void main (String [] args) {Tråd guruthread1 = ny tråd ();guruthread1.start ();Prova {guruthread1.sleep (1000);} fånga (InterruptedException e) {// TODO Auto-genererad fångstblocke.printStackTrace ();}guruthread1.setPriority (1);int gurupriority = guruthread1.getPriority ();System.out.println (gurupriority);System.out.println ("Tråd körs");}}

Förklaring av koden:

  • Kodrad 2: Vi skapar en klass "thread_Example1" som implementerar det körbara gränssnittet (det ska implementeras av alla klasser vars instanser är avsedda att köras av tråden.)
  • Kodrad 4: Den å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 körningen av tråden.
  • Kodrad 7: Här skapar vi ett nytt trådnamn som "guruthread1" genom att starta 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 köras.
  • Kodrad 10: Här använder vi "sleep" -metoden för tråden med "guruthread1" -instansen. Därför kommer tråden att sova i 1000 millisekunder.
  • Kod 9-14: Här har vi lagt sömnmetod i försök fångstblock eftersom det finns kontrollerat undantag som inträffar dvs Avbrutet undantag.
  • Kodrad 15: Här ställer vi in ​​trådens prioritet till 1 från vilken prioritet den var
  • Kodrad 16: Här får vi prioritet för tråden med hjälp av getPriority ()
  • Kodrad 17: Här skriver vi ut det värde som hämtats från getPriority
  • Kodrad 18: Här skriver vi en text som tråden körs.

När du kör koden ovan får du följande utdata:

Produktion:

5 är trådens prioritet, och trådkörning är texten som är resultatet av vår kod.

Java-trådsynkronisering

I multithreading finns programmenas asynkrona beteende. Om en tråd skriver 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 synkroniseringsmetoden.

Java har tillhandahållit synkroniserade metoder för att implementera synkroniserat beteende.

I detta tillvägagångssätt, när tråden når in i 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å detta sätt hjälper synkroniseringen i en applikation med flera trådar. En tråd måste vänta tills den andra har slutfört sin körning först då de andra trådarna får köras.

Det kan skrivas i följande form:

Synkroniserad (objekt){// Block av uttalanden som ska synkroniseras}

Java Multithreading Exempel

I det här exemplet tar vi två trådar och hämtar namnen på tråden.

Exempel 1:

GuruThread1.javapaket demotest;offentlig klass GuruThread1 implementerar Runnable {/ *** @param argumenterar* /public static void main (String [] args) {Tråd guruThread1 = ny tråd ("Guru1");Tråd guruThread2 = ny tråd ("Guru2");guruThread1.start ();guruThread2.start ();System.out.println ("Trådnamnen är följande:");System.out.println (guruThread1.getName ());System.out.println (guruThread2.getName ());}@Åsidosättaoffentlig ogiltig körning () {}}

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 köras av tråden.)
  • Kodrad 8: Detta är klassens huvudmetod
  • Kodrad 9: Här startar vi trådklassen och skapar en instans som heter "guruThread1" och skapar en tråd.
  • Kodrad 10: Här startar vi trådklassen 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: Mata ut texten som "Trådnamn följer:"
  • Kodrad 14: Få namnet på tråd 1 med hjälp av metoden getName () för trådklassen.
  • Kodrad 15: Få namnet på tråd 2 med metoden getName () för trådklassen.

När du kör koden ovan får du följande utdata:

Produktion:

Trådnamn matas ut här som

  • Guru1
  • Guru2

Exempel 2:

I det här exemplet lär vi oss om övergripande metoder run () och start () -metoden för ett körbart gränssnitt och skapa två trådar av den klassen och köra dem därefter.

Vi tar också två klasser,

  • En som kommer att implementera det körbara gränssnittet och
  • En annan som kommer att ha huvudmetoden och utföra därefter.
paket demotest;offentlig klass GuruThread2 {public static void main (String [] args) {// TODO Auto-genererad metodstubGuruThread3 threadguru1 = ny GuruThread3 ("guru1");threadguru1.start ();GuruThread3 threadguru2 = ny GuruThread3 ("guru2");threadguru2.start ();}}klass GuruThread3 implementerar Runnable {Tråd guruthread;privat stränggurunamn;GuruThread3 (strängnamn) {gurunamn = namn;}@Åsidosättaoffentlig ogiltig körning () {System.out.println ("Thread running" + guruname);för (int i = 0; i <4; i ++) {System.out.println (i);System.out.println (gurunamn);Prova {Thread.sleep (1000);} fånga (InterruptedException e) {System.out.println ("Tråden har avbrutits");}}}offentlig ogiltig start () {System.out.println ("Tråd startad");if (guruthread == null) {guruthread = ny tråd (detta, gurunamn);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 förekomst av klass GuruThread3 (som skapas nedanför raderna i koden) som "threadguru1" och vi börjar tråden.
  • Kodrad 8-9: Här skapar vi en annan instans av klass GuruThread3 (som skapas under raderna 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 ska implementeras av alla klasser vars instanser är avsedda att köras av tråden.)
  • Kodrad 13-14: vi tar två klassvariabler från vilka en är av typen trådklass och en annan av strängklassen.
  • Kodrad 15-18: vi åsidosätter GuruThread3-konstruktorn, som tar ett argument som strängtyp (vilket är trådnamn) som tilldelas klassvariabeln gurunamn och därmed lagras namnet på tråden.
  • Kodrad 20: Här åsidosätter vi körningsmetoden () för det körbara gränssnittet.
  • Kodrad 21: Vi skriver ut trådnamnet med hjälp av println-uttalandet.
  • Kodlinje 22-31: Här använder vi en for-loop med räknaren initialiserad till 0, och den ska inte vara mindre än 4 (vi kan ta vilket tal som helst, här kommer loop att köras fyra gånger) och öka räknaren. Vi skriver ut trådnamnet och låter också tråden sova i 1000 millisekunder inom ett försök-fångstblock som sömnmetod höjde kontrollerat undantag.
  • Kodrad 33: Här överstyr vi startmetoden för det körbara gränssnittet.
  • Kodrad 35: Vi skriver ut texten "Tråd startad".
  • Kodrad 36-40: Här tar vi ett if-villkor för att kontrollera om klassvariabel guruthread har värde i sig eller nr. Om det är null skapar vi en instans med hjälp av trådklass som tar namnet som en parameter (värde för vilket tilldelades i konstruktorn). Därefter startas tråden med start () -metoden.

När du kör koden ovan får du följande utdata:

Utgång :

Det finns två trådar så vi får två gånger meddelandet "Tråd startad".

Vi får namnen på tråden när vi har skickat ut dem.

Det går in för loop 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örst får vi guru1 sedan guru2 sedan igen guru2 eftersom tråden sover här i 1000 millisekunder och sedan nästa guru1 och igen guru1, tråden 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 enstaka och flera trådar.

  • Vid flertrådning blockeras inte användare eftersom trådar är oberoende och kan utföra flera operationer samtidigt
  • Olika stadier av trådens livscykel är,
    • Ny
    • Körbar
    • Löpning
    • Väntar
    • Död
  • Vi lärde oss också om synkronisering mellan trådar, vilket hjälper applikationen att fungera smidigt.
  • Multithreading underlättar många fler applikationsuppgifter.