Multithreading i Java Tutorial med program og eksempler


Enhver applikation kan have flere processer (instanser). Hver af disse processer kan tildeles enten som en enkelt tråd eller flere tråde. Vi vil se i denne tutorial, hvordan du udfører flere opgaver på samme tid og lærer også mere om tråde og synchronisering mellem tråde.

I denne Multithreading-tutorial i Java lærer vi:

Hvad er enkelt tråd?

En enkelt tråd i Java er dybest set en letvægts og den mindste behandlingsenhed. Java bruger tråde ved at bruge en "Trådklasse".

Der er to typer tråd - brugertråd og dæmontråd (Dæmontråde bruges når vi vil rense applikationen og bruges i baggrunden).

Når en applikation først starter, oprettes brugertråd. Post det, vi kan oprette mange brugertråde og dæmontråde.

Eksempel på enkelt tråd:

package demotest;

public class GuruThread
{
       public static void main(String[] args) {
              System.out.println("Single Thread");
       }
}

Fordele ved enkelt gevind:

  • Reducerer overhead i applikationen som enkelttråds eksekvering i systemet
  • Det reducerer også vedligeholdelsesomkostningerne for applikationen.

Hvad er Multithreading i Java?

multithreading i Java er en proces med at udføre to eller flere tråde samtidigtneonormalt til maksimal udnyttelse af CPU. Multitrådede applikationer udfører to eller flere tråde, der kører samtidigt. Derfor er det også kendt som Concurrency i Java. Hver tråd løber parallelt med hinanden. Flere tråde tildeler ikke separat hukommelsesområde, derfor sparer de hukommelse. Desuden tager kontekstskift mellem tråde mindre tid.

Eksempel 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() {
    }
}

Fordele ved multithread:

  • Brugerne er ikke blokeret, fordi tråde er uafhængige, og vi kan udføre flere operationer til tider
  • Som sådan er trådene uafhængige, de andre tråde vil ikke blive påvirket, hvis en tråd møder en undtagelse.

Trådens livscyklus i Java

En tråds livscyklus:

Trådens livscyklus i Java
Trådens livscyklus i Java

Der er forskellige stadier af trådens livscyklus som vist i ovenstående diagram:

  1. Ny
  2. Kan køres
  3. Løb
  4. Venter
  5. Dead
  1. Nyt: I denne fase oprettes tråden ved hjælp af klassen "Trådklasse". Den forbliver i denne tilstand indtil programmet starter tråden. Det er også kendt som født tråd.
  2. Kan køres: På denne side kaldes forekomsten af ​​tråden med en startmetode. Trådstyringen gives til skemalæggeren for at afslutte udførelsen. Det afhænger af planlæggeren, om tråden skal køres.
  3. Løb: Når tråden begynder at køre, ændres tilstanden til "kører". Planlæggeren vælger en tråd fra trådpuljen, og den begynder at køre i applikationen.
  4. Venter: Dette er tilstanden, når en tråd skal vente. Da der kører flere tråde i applikationen, er der behov for synchronisering mellem tråde. Derfor må den ene tråd vente, indtil den anden tråd bliver udført. Derfor omtales denne tilstand som ventetilstand.
  5. Død: Dette er tilstanden, når tråden afsluttes. Tråden er i kørende tilstand, og så snart den afsluttede behandlingen, er den i "død tilstand".


Nogle af de almindeligt anvendte metoder til tråde er:

Metode Beskrivelse
Start() Denne metode starter udførelsen af ​​tråden og FMV kalder run()-metoden på tråden.
Søvn (int millisekunder) Denne metode får tråden til at sove, hvorfor trådens udførelse pauser i millisekunder forudsat, og derefter begynder tråden igen at køre. Dette hjælper i synchronisering af trådene.
getName () Det returnerer navnet på tråden.
setPriority(int newpriority) Det ændrer trådens prioritet.
udbytte () Det får den aktuelle tråd til at stoppe og andre tråde til at udføre.

Eksempel: I dette multithreading-program i Java-eksempel skal vi oprette en tråd og udforske indbyggede metoder, der er tilgængelige for tråde.

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");
  }
}

Forklaring af koden:

  • Kodelinje 2: Vi opretter en klasse "thread_Example1", som implementerer Runnable-grænsefladen (den bør implementeres af enhver klasse, hvis instanser er beregnet til at blive udført af tråden).
  • Kodelinje 4: Den tilsidesætter kørselsmetoden for den kørselsbare grænseflade, da det er obligatorisk at tilsidesætte denne metode
  • Kodelinje 6: Her har vi defineret hovedmetoden, hvor vi vil starte udførelsen af ​​tråden.
  • Kodelinje 7: Her opretter vi et nyt trådnavn som "guruthread1" ved at instantiere en ny klasse af tråd.
  • Kodelinje 8: vi vil bruge "start" metoden for tråden ved hjælp af "guruthread1" forekomst. Her vil tråden begynde at køre.
  • Kodelinje 10: Her bruger vi "sleep"-metoden for tråden ved hjælp af "guruthread1"-forekomst. Derfor vil tråden sove i 1000 millisekunder.
  • Kode 9-14: Her har vi sat sleep-metoden i try catch-blok, da der er markeret undtagelse, som opstår, dvs. Afbrudt undtagelse.
  • Kodelinje 15: Her sætter vi trådens prioritet til 1 fra hvilken prioritet det var
  • Kodelinje 16: Her får vi trådens prioritet ved hjælp af getPriority()
  • Kodelinje 17: Her udskriver vi værdien hentet fra getPriority
  • Kodelinje 18: Her skriver vi en tekst, som tråden kører.

Når du udfører ovenstående kode, får du following produktion:

Trådeksempel i Java

Output:

5 er trådprioriteten, og trådløb er teksten, som er outputtet af vores kode.

Java-tråd Synchronisering

I multithreading er der ensyncprogrammernes ærlige opførsel. Hvis en tråd skriver nogle data og en anden tråd som læser data på samme tid, kan det skabe inkonsistens i applikationen.

Når der er behov for at få adgang til de delte ressourcer via to eller flere tråde, så synchroniseringstilgang anvendes.

Java har givet synchroniserede metoder til at implementere synchroniseret adfærd.

I denne tilgang, når tråden når inde i synchroniseret blok, så kan ingen anden tråd kalde den metode på det samme objekt. Alle tråde skal vente til den tråd er færdig synchroniseret blok og kommer ud af det.

På denne måde synchronisering hjælper i en flertrådsapplikation. Én tråd skal vente, indtil den anden tråd afslutter sin udførelse, så er de andre tråde tilladt til udførelse.

Det kan skrives i folloenwing form:

Synchronized(object)
{  
        //Block of statements to be synchronized
}

Eksempel på Java Multithreading

I dette multithreading Java-eksempel tager vi to tråde og henter navnene på tråden.

Eksempel 1:

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() {
    }
}

Forklaring af koden:

  • Kodelinje 3: Vi har taget en klasse "GuruThread1", som implementerer Runnable (den bør implementeres af enhver klasse, hvis instanser er beregnet til at blive udført af tråden.)
  • Kodelinje 8: Dette er klassens vigtigste metode
  • Kodelinje 9: Her instansierer vi Thread-klassen og opretter en instans med navnet "guruThread1" og opretter en tråd.
  • Kodelinje 10: Her instansierer vi Thread-klassen og opretter en instans ved navn "guruThread2" og opretter en tråd.
  • Kodelinje 11: Vi starter tråden dvs. guruThread1.
  • Kodelinje 12: Vi starter tråden dvs. guruThread2.
  • Kodelinje 13: Udskriver teksten som "Trådnavne er following:”
  • Kodelinje 14: Hentning af navnet på tråd 1 ved hjælp af metoden getName() i trådklassen.
  • Kodelinje 15: Hentning af navnet på tråd 2 ved hjælp af metoden getName() i trådklassen.

Når du udfører ovenstående kode, får du following produktion:

Eksempel på Java Multithreading

Output:

Trådnavne udsendes her som

  • Guru1
  • Guru2

Eksempel 2:

I dette multithreading i Java-eksempel vil vi lære om tilsidesættelse af metoderne run() og start()-metoden for en kørebar grænseflade og oprette to tråde af den klasse og køre dem i overensstemmelse hermed.

Desuden tager vi to klasser,

  • En som vil implementere den kørebare grænseflade og
  • En anden, som vil have hovedmetoden og udføre i overensstemmelse hermed.
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();
  }
 }
}

Forklaring af koden:

  • Kodelinje 2: Her tager vi en klasse "GuruThread2", som vil have hovedmetoden i sig.
  • Kodelinje 4: Her tager vi en hovedmetode i klassen.
  • Kodelinje 6-7: Her opretter vi en forekomst af klassen GuruThread3 (som er oprettet i nedenstående linjer i koden) som "threadguru1", og vi starter tråden.
  • Kodelinje 8-9: Her opretter vi endnu en forekomst af klassen GuruThread3 (som er oprettet i nedenstående linjer i koden) som "threadguru2", og vi starter tråden.
  • Kodelinje 11: Her opretter vi en klasse "GuruThread3", som implementerer den kørebare grænseflade (den bør implementeres af enhver klasse, hvis forekomster er beregnet til at blive udført af tråden.)
  • Kodelinje 13-14: vi tager to klassevariabler, hvorfra den ene er af typen trådklasse og den anden af ​​strengklassen.
  • Kodelinje 15-18: vi tilsidesætter GuruThread3-konstruktøren, som tager ét argument som strengtype (som er trådens navn), der bliver tildelt klassevariablen guruname, og derfor lagres navnet på tråden.
  • Kodelinje 20: Her tilsidesætter vi run()-metoden for den kørbare grænseflade.
  • Kodelinje 21: Vi udskriver trådnavnet ved hjælp af println-sætning.
  • Kodelinje 22-31: Her bruger vi en for-løkke med tæller initialiseret til 0, og den bør ikke være mindre end 4 (vi kan tage et hvilket som helst tal, derfor vil løkken køre 4 gange) og øge tælleren. Vi udskriver trådnavnet og gør også tråden i dvale i 1000 millisekunder inden for en try-catch-blok, da søvnmetoden hævede kontrolleret undtagelse.
  • Kodelinje 33: Her tilsidesætter vi startmetoden for den kørebare grænseflade.
  • Kodelinje 35: Vi udskriver teksten "Tråd startet".
  • Kodelinje 36-40: Her tager vi en if-betingelse for at kontrollere, om klassevariablen guruthread har værdi i sig eller ej. Hvis det er null, opretter vi en instans ved hjælp af trådklasse, som tager navnet som en parameter (værdien, som blev tildelt i konstruktøren). Hvorefter tråden startes ved hjælp af start() metoden.

Når du udfører ovenstående kode, får du following produktion:

Multithreading eksempel i Java

Produktion:

Der er to tråde, derfor får vi to gange beskeden "Tråd startet".

Vi får navnene på tråden, som vi har udskrevet dem.

Det går ind i for loop, hvor vi udskriver tælleren og trådnavnet og tælleren starter med 0.

Sløjfen udføres tre gange og ind imellem sover tråden i 1000 millisekunder.

Derfor får vi først guru1, derefter guru2, så igen guru2, fordi tråden sover her i 1000 millisekunder, og derefter den næste guru1 og igen guru1, tråden sover i 1000 millisekunder, så vi får guru2 og derefter guru1.

Resumé

I denne tutorial så vi flertrådede applikationer i Java, og hvordan man bruger single og multi thread i Java.

  • Forklar multithreading i Java: i multithreading blokeres brugere ikke, da tråde er uafhængige og kan udføre flere operationer på tidspunktet
  • Forskellige stadier af trådens livscyklus er,
    • Ny
    • Kan køres
    • Løb
    • Venter
    • Dead
  • Vi lærte også om synchronisering mellem tråde, som hjælper applikationen til at køre problemfrit.
  • Multithreaded programmering i Java gør mange flere applikationsopgaver nemmere.