Mutex in Java

Haider Ali 15 Februar 2024
  1. Threading und Multithreading
  2. Threads in Java
  3. Mutex
  4. Erläuterung
Mutex in Java

In der Welt der Informatik ist Mutual Exclusion oder Mutex als Eigenschaft der Parallelitätskontrolle bekannt. Jeder Computer arbeitet die kleinste Sequenz von programmierten Befehlen, die als Thread bekannt sind. Der Computer arbeitet gleichzeitig an einem einzelnen Thread. Lassen Sie uns zum besseren Verständnis in einige weitere Aspekte eintauchen.

Threading und Multithreading

CPU arbeitet an Threads für Multitasking. Jeder Prozess funktioniert, indem er ständig mit sehr hoher Geschwindigkeit von Thread zu Thread wechselt. Wenn wir uns beispielsweise ein Video ansehen, befindet sich der Ton des Videos in einem anderen Thread und das Bild in einem anderen. Der ständige Wechsel zwischen diesen beiden ist sehr schnell und wird als Multithreading bezeichnet.

Threads in Java

Das Erstellen eines Threads in Java erfolgt durch das Erweitern einer Klasse und das Implementieren einer Schnittstelle. Multithreading ist eine Java-Funktion, die die gleichzeitige Ausführung von zwei oder mehr Teilen eines Programms ermöglicht, um die CPU-Effizienz zu maximieren. Ein Thread ist ein Bestandteil eines solchen Programms. Threads sind daher leichtgewichtige Prozesse innerhalb von Prozessen.

Mutex

In einem Multithread-Programm müssen möglicherweise zwei oder mehr Threads gleichzeitig auf eine gemeinsam genutzte Ressource zugreifen, was zu unerwartetem Verhalten führt. Datenstrukturen, Eingabe-Ausgabe-Geräte, Dateien und Netzwerkverbindungen sind Beispiele für gemeinsam genutzte Ressourcen.

Dies wird als Race-Condition bezeichnet. Der Schlüsselabschnitt des Programms ist der Teil des Programms, der auf die gemeinsam genutzte Ressource zugreift. Als Ergebnis müssen wir den Zugriff auf den kritischen Teil synchronisieren, um eine Race-Condition zu vermeiden.

Die einfachste Art von Synchronizer ist ein Mutex (oder gegenseitiger Ausschluss), der sicherstellt, dass nur ein Thread den wesentlichen Bereich eines Computerprogramms gleichzeitig ausführen kann. Es wird von einer Klasse namens semaphore implementiert.

Ein Thread ruft den Mutex ab, greift dann auf den entscheidenden Abschnitt zu und gibt schließlich den Mutex frei, um auf einen kritischen Bereich zuzugreifen. Währenddessen werden alle anderen Threads blockiert, bis der Mutex freigegeben wird. Ein Thread kann in den kritischen Abschnitt eintreten, sobald er den kritischen Bereich verlässt.

Für Mutex gibt es zwei Methoden zum Sperren und Entsperren. Sie werden als acquire() bzw. release() bezeichnet. Sehen Sie sich nun das Beispiel unten an.

Erfahren Sie mehr über Mutex hier.

import java.util.LinkedList; // linked list import
import java.util.concurrent.Semaphore; // semaphore import
public class Mutex {
  static LinkedList<String> WorkingQueue = new LinkedList<String>();
  // track the record of works
  static Semaphore mutex1 = new Semaphore(0); // creating a Semaphore To ImplementLogic
  static Semaphore mutex = new Semaphore(1); // Creating A Mutex
}

Im obigen Beispiel haben wir zwei Mutex-Objekte mit den Namen mutex und mutex1 erstellt. Wir verwenden mutex1, um den Wechsel zwischen zwei Threads zu steuern. Der Grund für das Erstellen der verknüpften Liste besteht darin, eine Erfolgsbilanz von Threads zu haben. Jetzt fügen wir zwei Threads in den obigen Code ein. Zwei Threads mit den Namen Producer und Consumer.

import java.util.LinkedList; // linked list import
import java.util.concurrent.Semaphore; // semaphore import
public class Mutex {
  static LinkedList<String> WorkingQueue = new LinkedList<String>();
  // track the record of works
  static Semaphore mutex1 = new Semaphore(0); // creating a Semaphore To ImplementLogic
  static Semaphore mutex = new Semaphore(1); // Creating A Mutex
  static class Producer extends Thread {
    public void run() { // default run method of thread
      int counter = 1;
      try {
        while (true) {
          String threadName = Thread.currentThread().getName()
              + counter++; // counter is added to have the thread number being used

          mutex.acquire(); // Acquiring  Lock  before Producing so the consumer cannot consume.
          WorkingQueue.add(threadName);
          System.out.println("Producer is prdoucing producing: " + threadName);
          mutex.release(); // releasing After Production ;
          mutex1.release(); // relesing lock for consumer...so consumer can consume after production
          Thread.sleep(2000); // just to Reduce the Execution Speed
        }
      } catch (Exception e) { /*nothing */
      }
    }
  }
  static class Consumer extends Thread {
    String consumerName;
    public Consumer(String name) {
      this.consumerName = name;
    }
    public void run() {
      try {
        while (true) {
          mutex1.acquire(); /// Again Acquiring So no production while consuming
          mutex.acquire(); // Acquring Other consumers lock one consume at one time
          String result = "";
          for (String value : WorkingQueue) {
            result = value + ",";
          }
          System.out.println(consumerName + " consumes value: " + result
              + "Total Size working Queue Size " + WorkingQueue.size() + "\n");
          mutex.release(); // releasing lock for other consumers.
        }
      } catch (Exception e) {
      }
    }
    public static void main(String[] args) {
      Producer producer = new Producer();

      producer.start();
      Consumer c1 = new Consumer("Bill Gates");
      Consumer c2 = new Consumer("Jeff Bezoz");
      Consumer c3 = new Consumer("Mark Zukerberg");
      c1.start();
      c2.start();
      c3.start();
    }
  }
}

Erläuterung

Der obige Code ist ebenfalls selbsterklärend, aber diese Erklärung wird die Verwirrung beseitigen.

Im Producer-Thread

Wenn Sie das obige Programm ausführen, erstellt es einen producer-Thread. Innerhalb dieses Threads gibt es eine while-Schleife, die auf unbestimmte Zeit ausgeführt wird. Der String threadName dient nur zur Anzeige der Thread-Ausführung. Das Objekt mutex erhält die Sperre, damit der Consumer-Thread funktionsfähig ist. (Der Hauptzweck von Mutex, die Kontrolle über die Parallelität zu erlangen).

Danach wird der Thread Produzent funktionsfähig. Dann müssen wir diesen Thread für die Produktion freigeben. Im Thread producer werden wir mutex1 freigeben, das Objekt, das für den Wechsel zwischen consumer und producer zuständig ist. Nach der Freigabe beginnen die Verbraucher zu konsumieren, dh der Thread consumer wird funktionsfähig sein.

Im Consumer-Thread

Gleich nachdem wir in den consumer-Thread eingestiegen sind, haben wir mutex1 erworben, um die Produktion während des Konsums zu stoppen. Wie Sie sehen, haben wir drei Konsumenten unter den Namen C1, C2 und C3 angelegt. Damit ein Konsument gleichzeitig funktionstüchtig sein kann, haben wir auch mutex erworben.

Danach wird C1 funktionsfähig, während C2 und C3 erfasst werden. Nach Abschluss wird mutex wieder freigegeben, damit der andere Konsument funktionsfähig ist.

So funktioniert Mutex in Java. Nachdem Sie das obige Programm ausgeführt haben. Es zeigt ständig die aktuelle Anzahl der verwendeten producer-Threads und den Namen des consumers an, der diese verwendet.

Java-Mutex-Beispiel

Die Größe wird während der Ausführung des Programms weiter erhöht.

Autor: Haider Ali
Haider Ali avatar Haider Ali avatar

Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.

LinkedIn

Verwandter Artikel - Java Threading