CodeGym /Java-Kurse /Modul 3: Java Professional /Synchronizer: Synchronisieren des Zugriffs auf Ressourcen...

Synchronizer: Synchronisieren des Zugriffs auf Ressourcen in Java

Modul 3: Java Professional
Level 19 , Lektion 4
Verfügbar

Semaphor

Semaphore werden normalerweise verwendet, wenn beim Arbeiten mit dem Dateisystem die Anzahl der Threads begrenzt werden muss. Der Zugriff auf eine Datei oder eine andere gemeinsam genutzte Ressource wird über einen Zähler gesteuert. Ist sein Wert größer als Null, ist der Zugriff erlaubt, gleichzeitig sinkt aber der Zähler.

In dem Moment, in dem der Zähler Null zurückgibt, wird der aktuelle Thread blockiert, bis die Ressource von einem anderen Thread freigegeben wird. Der Parameter „Anzahl der Berechtigungen“ muss über den Konstruktor festgelegt werden.

Sie müssen diesen Parameter je nach Leistung Ihres Computers oder Laptops individuell auswählen.

public class Main {

   public static void main(String[] args) {
       Semaphore sem = new Semaphore(1);
       CommonResource res = new CommonResource();
       new Thread(new MyThread(res, sem, "MyThread_1")).start();
       new Thread(new MyThread(res, sem, "MyThread_2")).start();
       new Thread(new MyThread(res, sem, "MyThread_3")).start();
   }
}

class CommonResource {
   int value = 0;
}

class MyThread implements Runnable {
   CommonResource commonResource;
   Semaphore semaphore;
   String name;
   MyThread(CommonResource commonResource, Semaphore sem, String name) {
       this.commonResource = commonResource;
       this.semaphore = sem;
       this.name = name;
   }

   public void run() {

       try {
           System.out.println(name + "waiting permission");
           semaphore.acquire();
           commonResource.value = 1;
           for (int i = 1; i < 7; i++) {
               System.out.println(this.name + ": " + commonResource.value);
               commonResource.value++;
               Thread.sleep(150);
           }
       } catch (InterruptedException e) {
           System.out.println(e.getMessage() + " " + name);
           Thread.currentThread().interrupt();
       }
       System.out.println(name + "releases permission");
       semaphore.release();
   }
}

CountDownLatch und andere

CountDownLatch – Ermöglicht mehreren Threads zu warten, bis eine bestimmte Anzahl von Vorgängen, die auf anderen Threads ausgeführt wurden, abgeschlossen ist. Ein Beispiel ist die Installation einer Anwendung: Sie wird erst gestartet, wenn Sie die Nutzungsbedingungen akzeptieren, bis Sie einen Ordner auswählen, in dem ein neues Programm installiert werden soll, usw. Hierfür gibt es eine spezielle countDown()- Methode – diese Methode dekrementiert den Countdown-Zähler um eins.

Sobald der Zähler auf Null geht, setzen alle wartenden Threads im Warten ihre Arbeit fort und alle nachfolgenden Aufrufe von Warten werden ohne Wartezeit durchlaufen. Der Countdown-Zähler ist ein einmaliger Zähler und kann nicht zurückgesetzt werden.

CyclicBarrier – wird verwendet, um eine bestimmte Anzahl von Threads an einem Punkt zu synchronisieren. Die Barriere wird erreicht, wenn N Threads die Methode „await(...)“ aufrufen und blockieren. Danach wird der Zähler auf seinen ursprünglichen Wert zurückgesetzt und die wartenden Threads werden freigegeben. Darüber hinaus ist es bei Bedarf möglich, benutzerdefinierten Code auszuführen, bevor Threads entsperrt und der Zähler zurückgesetzt werden. Dazu wird ein Objekt mit einer Implementierung der Runnable- Schnittstelle durch den Konstruktor geleitet .

Exchanger<V> – die Exchanger- Klasse ist für den Datenaustausch zwischen Threads gedacht. Es ist typisiert und gibt die Art der Daten ein, die die Threads austauschen müssen.

Der Datenaustausch erfolgt mit der einzigen Methode „exchange()“ dieser Klasse :

V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

Der x-Parameter stellt den auszutauschenden Datenpuffer dar. Die zweite Form der Methode definiert auch den Timeout- Parameter , den Timeout, und Unit , die Art der Zeiteinheit, die für den Timeout- Parameter verwendet werden soll .

Mit der Phaser- Klasse können Sie Threads synchronisieren, die eine einzelne Phase oder Stufe bei der Ausführung einer Gesamtaktion darstellen. Phaser definiert ein Synchronisationsobjekt, das wartet, bis eine bestimmte Phase abgeschlossen ist. Der Phaser geht dann zur nächsten Stufe oder Phase über und wartet darauf, dass diese erneut abgeschlossen wird.

Bei der Arbeit mit der Phaser- Klasse ist es üblich, zunächst deren Objekt zu erstellen. Als nächstes müssen wir alle Teilnehmer registrieren. Um sich für jeden Teilnehmer zu registrieren, wird die Methode register() aufgerufen , oder Sie können auf diese Methode verzichten, indem Sie die erforderliche Anzahl von Teilnehmern an den Phaser- Konstruktor übergeben .

Anschließend führt jeder Teilnehmer eine bestimmte Reihe von Aktionen aus, aus denen die Phase besteht. Und der Phaser- Synchronisator wartet, bis alle Teilnehmer die Ausführung der Phase abgeschlossen haben. Um den Synchronizer darüber zu informieren, dass die Phase beendet ist, muss der Teilnehmer die Methode Arrival() oder ArrivalAndAwaitAdvance() aufrufen . Anschließend geht der Synchronisierer zur nächsten Phase über.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION