Multithreading ind Java


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 i denne vejledning se, hvordan du udfรธrer flere opgaver pรฅ samme tid og lรฆrer ogsรฅ mere om trรฅde og synkronisering mellem trรฅde.

Hvad er enkelt trรฅd?

En enkelt trรฅd ind Java er dybest set en letvรฆgts og den mindste forarbejdningsenhed. 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 in Java er en proces med at udfรธre to eller flere trรฅde samtidigt 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 handlinger 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รฅd livscyklus ind Java

En trรฅds livscyklus:

Trรฅd livscyklus ind Java
Trรฅd livscyklus ind 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 synkronisering 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".


Metoder til multithreading i Java

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 med at synkronisere 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 for 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 fรธlgende output:

Trรฅd eksempel 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 programmernes asynkrone adfรฆrd. 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รฅ anvendes synkroniseringstilgang. Java har leveret synkroniserede metoder til at implementere synkroniseret adfรฆrd.

I denne tilgang, nรฅr trรฅden nรฅr ind i den synkroniserede blok, kan ingen anden trรฅd kalde den metode pรฅ det samme objekt. Alle trรฅde skal vente, indtil den trรฅd afslutter den synkroniserede blok og kommer ud af den. Pรฅ denne mรฅde hjรฆlper synkroniseringen 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 fรธlgende form:

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

Multithreading ind Java Eksempler pรฅ programmer

I denne multithreading Java for eksempel vil vi tage to trรฅde og hente 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 fรธlger:"
  • 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 fรธlgende output:

Java Multithreading eksempel

Output:

Trรฅdnavne udsendes her som

  • Guru1
  • Guru2

Eksempel 2:

I denne multithreading i Java for 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 fรธlgende output:

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 multitrรฅdede applikationer i Java og hvordan man bruger enkelt- og multitrรฅd i Java.

  • Forklar multithreading ind Java: i multithreading blokeres brugere ikke, da trรฅde er uafhรฆngige og kan udfรธre flere handlinger ad gangen
  • Forskellige stadier af trรฅdens livscyklus er,
    • Ny
    • Kan kรธres
    • Lรธb
    • Venter
    • Dead
  • Vi lรฆrte ogsรฅ om synkronisering mellem trรฅde, som hjรฆlper applikationen til at kรธre problemfrit.
  • Multithreaded programmering ind Java gรธr mange flere applikationsopgaver nemmere.

Opsummer dette indlรฆg med: