Multithreading in Java-Tutorial mit Programm und Beispielen


Jede Anwendung kann mehrere Prozesse (Instanzen) haben. Jeder dieser Prozesse kann entweder als einzelner Thread oder als mehrere Threads zugewiesen werden. In diesem Tutorial erfahren Sie, wie Sie mehrere Aufgaben gleichzeitig ausführen und erfahren mehr über Threads und die Synchronisierung zwischen Threads.

In diesem Multithreading-Tutorial in Java lernen wir:

Was ist Single-Thread?

Ein einzelner Thread in Java ist im Grunde eine leichte und kleinste Verarbeitungseinheit. Java verwendet Threads mithilfe einer „Thread-Klasse“.

Es gibt zwei Arten von Fäden – Benutzer-Thread und Daemon-Thread (Daemon-Threads werden verwendet, wenn wir die Anwendung bereinigen möchten, und werden im Hintergrund verwendet.)

Wenn eine Anwendung zum ersten Mal gestartet wird, wird ein Benutzerthread erstellt. Wenn wir das posten, können wir viele Benutzer-Threads und Daemon-Threads erstellen.

Beispiel für einen einzelnen Thread:

package demotest;

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

Vorteile von Single-Thread:

  • Reduziert den Overhead in der Anwendung, da ein einzelner Thread im System ausgeführt wird
  • Außerdem werden die Wartungskosten der Anwendung reduziert.

Was ist Multithreading in Java?

Multithreading In Java handelt es sich um einen Prozess, bei dem zwei oder mehr Threads gleichzeitig ausgeführt werdenneonormalerweise auf maximale Auslastung der CPU. Multithread-Anwendungen führen zwei oder mehr Threads gleichzeitig aus. Daher wird es in Java auch als Parallelität bezeichnet. Jeder Thread verläuft parallel zueinander. Mehrere Threads weisen keinen separaten Speicherbereich zu und sparen daher Speicher. Außerdem nimmt der Kontextwechsel zwischen Threads weniger Zeit in Anspruch.

Beispiel für Multithread:

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

Vorteile von Multithread:

  • Die Benutzer werden nicht blockiert, da Threads unabhängig sind und wir mehrere Vorgänge gleichzeitig ausführen können
  • Da die Threads unabhängig sind, sind die anderen Threads nicht betroffen, wenn ein Thread auf eine Ausnahme trifft.

Thread-Lebenszyklus in Java

Der Lebenszyklus eines Threads:

Thread-Lebenszyklus in Java
Thread-Lebenszyklus in Java

Es gibt verschiedene Phasen im Lebenszyklus eines Threads, wie im obigen Diagramm dargestellt:

  1. Neu
  2. Lauffähig
  3. Laufen
  4. Warten
  5. Tot
  1. Neu: In dieser Phase wird der Thread mithilfe der Klasse „Thread-Klasse“ erstellt. Er bleibt in diesem Zustand, bis das Programm ausgeführt wird beginnt der Faden. Es ist auch als Born Thread bekannt.
  2. Lauffähig: Auf dieser Seite wird die Instanz des Threads mit einer Startmethode aufgerufen. Die Thread-Steuerung wird dem Scheduler übergeben, um die Ausführung abzuschließen. Es hängt vom Scheduler ab, ob der Thread ausgeführt werden soll.
  3. Laufen: Wenn die Ausführung des Threads beginnt, ändert sich der Status in den Status „Wird ausgeführt“. Der Scheduler wählt einen Thread aus dem Thread-Pool aus und beginnt mit der Ausführung in der Anwendung.
  4. Warten: Dies ist der Zustand, in dem ein Thread warten muss. Da in der Anwendung mehrere Threads ausgeführt werden, ist eine Synchronisierung zwischen den Threads erforderlich. Daher muss ein Thread warten, bis der andere Thread ausgeführt wird. Daher wird dieser Zustand als Wartezustand bezeichnet.
  5. Tot: Dies ist der Zustand, wenn der Thread beendet wird. Der Thread befindet sich im laufenden Zustand und befindet sich, sobald er die Verarbeitung abgeschlossen hat, im „toten Zustand“.


Einige der häufig verwendeten Methoden für Threads sind:

Versandart Beschreibung
Start() Diese Methode startet die Ausführung des Threads und JVM ruft die run()-Methode für den Thread auf.
Schlaf (int Millisekunden) Diese Methode versetzt den Thread in den Ruhezustand, daher wird die Ausführung des Threads für einige Millisekunden angehalten, und danach beginnt der Thread erneut mit der Ausführung. Dies hilft bei der Synchronisierung der Threads.
getName () Es gibt den Namen des Threads zurück.
setPriority(int newpriority) Es ändert die Priorität des Threads.
Ertrag () Dadurch wird der aktuelle Thread angehalten und andere Threads ausgeführt.

Beispiel: In diesem Multithreading-Programm in Java-Beispiel erstellen wir einen Thread und erkunden die für Threads verfügbaren integrierten Methoden.

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

Erklärung des Codes:

  • Codezeile 2: Wir erstellen eine Klasse „thread_Example1“, die die Runnable-Schnittstelle implementiert (sie sollte von jeder Klasse implementiert werden, deren Instanzen vom Thread ausgeführt werden sollen).
  • Codezeile 4: Es überschreibt die Ausführungsmethode der ausführbaren Schnittstelle, da diese Methode unbedingt überschrieben werden muss
  • Codezeile 6: Hier haben wir die Hauptmethode definiert, mit der wir die Ausführung des Threads starten.
  • Codezeile 7: Hier erstellen wir einen neuen Thread-Namen als „guruthread1“, indem wir eine neue Thread-Klasse instanziieren.
  • Codezeile 8: Wir werden die „Start“-Methode des Threads mit der Instanz „guruthread1“ verwenden. Hier beginnt die Ausführung des Threads.
  • Codezeile 10: Hier verwenden wir die „sleep“-Methode des Threads mit der Instanz „guruthread1“. Daher schläft der Thread 1000 Millisekunden lang.
  • Code 9-14: Hier haben wir die Sleep-Methode in den Try-Catch-Block eingefügt, da dort eine überprüfte Ausnahme auftritt, dh eine unterbrochene Ausnahme.
  • Codezeile 15: Hier setzen wir die Priorität des Threads auf 1, unabhängig von der Priorität, die er hatte
  • Codezeile 16: Hier erhalten wir die Priorität des Threads mit getPriority()
  • Codezeile 17: Hier drucken wir den von getPriority abgerufenen Wert
  • Codezeile 18: Hier schreiben wir einen Text, in dem der Thread läuft.

Wenn Sie den obigen Code ausführen, erhalten Sie Folgendeswing Ausgabe:

Thread-Beispiel in Java

Ausgang:

5 ist die Thread-Priorität und Thread Running ist der Text, der die Ausgabe unseres Codes darstellt.

Java-Thread-Synchronisierung

Beim Multithreading gibt es das asynchrone Verhalten der Programme. Wenn ein Thread Daten schreibt und ein anderer Thread gleichzeitig Daten liest, kann es zu Inkonsistenzen in der Anwendung kommen.

Wenn zwei oder mehr Threads auf die gemeinsam genutzten Ressourcen zugreifen müssen, wird der Synchronisierungsansatz verwendet.

Java hat synchronisierte Methoden bereitgestellt, um synchronisiertes Verhalten zu implementieren.

Bei diesem Ansatz kann, sobald der Thread den synchronisierten Block erreicht, kein anderer Thread diese Methode für dasselbe Objekt aufrufen. Alle Threads müssen warten, bis dieser Thread den synchronisierten Block beendet und diesen verlässt.

Auf diese Weise hilft die Synchronisierung in einer Multithread-Anwendung. Ein Thread muss warten, bis der andere Thread seine Ausführung beendet hat. Erst dann dürfen die anderen Threads ausgeführt werden.

Es kann wie folgt geschrieben werdenwing bilden:

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

Beispiel für Java-Multithreading

In diesem Multithreading-Java-Beispiel nehmen wir zwei Threads und rufen die Namen der Threads ab.

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

Erklärung des Codes:

  • Codezeile 3: Wir haben eine Klasse „GuruThread1“ genommen, die Runnable implementiert (sie sollte von jeder Klasse implementiert werden, deren Instanzen vom Thread ausgeführt werden sollen).
  • Codezeile 8: Dies ist die Hauptmethode der Klasse
  • Codezeile 9: Hier instanziieren wir die Thread-Klasse, erstellen eine Instanz mit dem Namen „guruThread1“ und erstellen einen Thread.
  • Codezeile 10: Hier instanziieren wir die Thread-Klasse, erstellen eine Instanz mit dem Namen „guruThread2“ und erstellen einen Thread.
  • Codezeile 11: Wir starten den Thread, dh guruThread1.
  • Codezeile 12: Wir starten den Thread, dh guruThread2.
  • Codezeile 13: Ausgabe des Textes als „Thread-Namen sind following: "
  • Codezeile 14: Den Namen von Thread 1 mithilfe der Methode getName() der Thread-Klasse ermitteln.
  • Codezeile 15: Den Namen von Thread 2 mithilfe der Methode getName() der Thread-Klasse ermitteln.

Wenn Sie den obigen Code ausführen, erhalten Sie Folgendeswing Ausgabe:

Beispiel für Java-Multithreading

Ausgang:

Thread-Namen werden hier ausgegeben als

  • Guru1
  • Guru2

Beispiel 2:

In diesem Beispiel für Multithreading in Java lernen wir das Überschreiben der Methoden run() und start() einer ausführbaren Schnittstelle kennen, erstellen zwei Threads dieser Klasse und führen sie entsprechend aus.

Außerdem nehmen wir an zwei Kursen teil,

  • Eines, das die ausführbare Schnittstelle implementiert und
  • Eine andere, die die Hauptmethode hat und entsprechend ausgeführt wird.
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();
  }
 }
}

Erklärung des Codes:

  • Codezeile 2: Hier nehmen wir eine Klasse „GuruThread2“, die die Hauptmethode enthalten wird.
  • Codezeile 4: Hier nehmen wir eine Hauptmethode der Klasse.
  • Codezeile 6-7: Hier erstellen wir eine Instanz der Klasse GuruThread3 (die in den folgenden Zeilen des Codes erstellt wird) als „threadguru1“ und starten den Thread.
  • Codezeile 8-9: Hier erstellen wir eine weitere Instanz der Klasse GuruThread3 (die in den folgenden Zeilen des Codes erstellt wird) als „threadguru2“ und starten den Thread.
  • Codezeile 11: Hier erstellen wir eine Klasse „GuruThread3“, die die ausführbare Schnittstelle implementiert (sie sollte von jeder Klasse implementiert werden, deren Instanzen vom Thread ausgeführt werden sollen).
  • Codezeile 13-14: Wir nehmen zwei Klassenvariablen, von denen eine vom Typ Thread-Klasse und die andere vom Typ String-Klasse ist.
  • Codezeile 15-18: Wir überschreiben den GuruThread3-Konstruktor, der ein Argument als String-Typ (den Thread-Namen) akzeptiert, der der Klassenvariablen guruname zugewiesen wird und somit den Namen des Threads speichert.
  • Codezeile 20: Hier überschreiben wir die run()-Methode der ausführbaren Schnittstelle.
  • Codezeile 21: Wir geben den Thread-Namen mit der println-Anweisung aus.
  • Codezeile 22-31: Hier verwenden wir eine for-Schleife mit einem auf 0 initialisierten Zähler, der nicht kleiner als 4 sein sollte (wir können jede beliebige Zahl annehmen, daher wird die Schleife hier viermal ausgeführt) und erhöhen den Zähler. Wir geben den Thread-Namen aus und sorgen dafür, dass der Thread innerhalb eines Try-Catch-Blocks 4 Millisekunden lang in den Ruhezustand versetzt wird, da die Sleep-Methode eine geprüfte Ausnahme auslöst.
  • Codezeile 33: Hier überschreiben wir die Startmethode der ausführbaren Schnittstelle.
  • Codezeile 35: Wir geben den Text „Thread gestartet“ aus.
  • Codezeile 36-40: Hier verwenden wir eine if-Bedingung, um zu prüfen, ob die Klassenvariable guruthread einen Wert enthält oder nicht. Wenn es null ist, erstellen wir eine Instanz mithilfe der Thread-Klasse, die den Namen als Parameter verwendet (der Wert wurde im Konstruktor zugewiesen). Danach wird der Thread mit der Methode start() gestartet.

Wenn Sie den obigen Code ausführen, erhalten Sie Folgendeswing Ausgabe:

Multithreading-Beispiel in Java

Output:

Da es zwei Threads gibt, erhalten wir zweimal die Meldung „Thread gestartet“.

Wir erhalten die Namen der Threads so, wie wir sie ausgegeben haben.

Es geht in die for-Schleife, in der wir den Zähler und den Thread-Namen drucken und der Zähler mit 0 beginnt.

Die Schleife wird dreimal ausgeführt und dazwischen ruht der Thread für 1000 Millisekunden.

Daher erhalten wir zuerst Guru1, dann Guru2 und dann noch einmal Guru2, weil der Thread hier 1000 Millisekunden lang schläft, und dann folgt Guru1 und wieder Guru1, der Thread schläft 1000 Millisekunden lang, also erhalten wir Guru2 und dann Guru1.

Zusammenfassung

In diesem Tutorial haben wir Multithread-Anwendungen in Java gesehen und erfahren, wie man Single- und Multi-Threads in Java verwendet.

  • Erklären Sie Multithreading in Java: Beim Multithreading werden Benutzer nicht blockiert, da Threads unabhängig sind und mehrere Vorgänge gleichzeitig ausführen können
  • Verschiedene Phasen des Lebenszyklus des Threads sind:
    • Neu
    • Lauffähig
    • Laufen
    • Warten
    • Tot
  • Wir haben auch davon erfahren Synchronisation zwischen Threads, die dazu beitragen, dass die Anwendung reibungslos läuft.
  • Die Multithread-Programmierung in Java erleichtert viele weitere Anwendungsaufgaben.