Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 10)

javathread.jpeg

Arbeiterfadenmuster

Arbeiter bedeutet "Arbeiter". Im WorkerThread-Muster arbeiten ** Arbeitsthreads ** nacheinander und verarbeiten sie. Wenn kein Job vorhanden ist, wartet der Worker-Thread auf einen neuen Job. Worker Thread wird manchmal als ** Hintergrund-Thread ** bezeichnet.

Betrachten Sie das folgende Beispiel. Ein Thread in der ClientThread-Klasse sendet eine Jobanforderung an die Channel-Klasse. Eine Instanz der Channel-Klasse verfügt über fünf Worker-Threads. Der Worker-Thread wartet auf eine Jobanforderung. Wenn eine Jobanforderung eintrifft, empfängt der Arbeitsthread eine Jobanforderung von Channel und verarbeitet sie. Wenn der Vorgang abgeschlossen ist, kehrt der Worker-Thread zu Channel zurück und wartet auf die nächste Anforderung.

(Den gesamten Code finden Sie in diesem Handbuch.)

Main.java


public class Main { 
    public static void main(String[] args) { 
        Channel channel = new Channel(5);   //Erstellen Sie 5 Arbeitsthreads
        channel.startWorkers(); //Starten Sie einen Worker-Thread
        new ClientThread("Alice", channel).start();  //Starten Sie einen Thread, um eine Jobanfrage zu stellen
        new ClientThread("Bobby", channel).start(); 
        new ClientThread("Chris", channel).start(); 
    } 
}

ClientThread.java


public class ClientThread extends Thread { 
    ...
    public void run() { 
        try { 
            for (int i = 0; true; i++) { 
                Request request = new Request(getName(), i); 
                channel.putRequest(request);  //Stellen Sie eine Jobanfrage
                Thread.sleep(random.nextInt(1000)); 
            } 
        } catch (InterruptedException e) { 
        } 
    } 
}

Channel.java


public class Channel { 
    private static final int MAX_REQUEST = 100; 
    private final Request[] requestQueue; 
    private int tail;
    private int head;
    private int count;
 
    private final WorkerThread[] threadPool; 
 
    public Channel(int threads) { 
        this.requestQueue = new Request[MAX_REQUEST]; 
        this.head = 0; 
        this.tail = 0; 
        this.count = 0; 
 
        threadPool = new WorkerThread[threads]; 
        for (int i = 0; i < threadPool.length; i++) { 
            threadPool[i] = new WorkerThread("Worker-" + i, this); 
        } 
    }

    public void startWorkers() { 
        for (int i = 0; i < threadPool.length; i++) { 
            threadPool[i].start(); 
        } 
    }

    public synchronized void putRequest(Request request) { 
        while (count >= requestQueue.length) { 
            try { 
                wait(); 
            } catch (InterruptedException e) { 
            } 
        } 
        requestQueue[tail] = request; 
        tail = (tail + 1) % requestQueue.length; 
        count++; 
        notifyAll(); 
    }

    public synchronized Request takeRequest() { 
        while (count <= 0) { 
            try { 
                wait(); 
            } catch (InterruptedException e) { 
            } 
        } 
        Request request = requestQueue[head]; 
        head = (head + 1) % requestQueue.length; 
        count--; 
        notifyAll(); 
        return request; 
    } 
}

WorkerThread.java


public class WorkerThread extends Thread { 
    ...
    public void run() { 
        while (true) { 
            Request request = channel.takeRequest(); //Geh und hol dir einen Job
            request.execute(); 
        } 
    } 
}

Die Channel-Klasse verfügt über ein Feld namens requestQueue zum Übergeben von Arbeitsanforderungen. Die putRequest-Methode stellt eine Anforderung in diese Warteschlange und die takeRequest-Methode ruft sie ab. Hier wird das Producer-Consumer-Muster verwendet. Das Thread-Per-Message-Muster hat bei jeder Ausführung eines Jobs einen neuen Thread erzeugt. Im Worker-Thread-Muster führen ** Worker-Threads die Arbeit jedoch wiederholt aus, sodass kein neuer Thread gestartet werden muss. ** WorkerThread verfügt nur über eine Channel-Instanz, um eine Jobanfrage zu erhalten, und weiß nichts über den jeweiligen Job.

Charakter

Kundenrolle Die Client-Rolle erstellt eine Jobanforderung als Anforderungsrolle und übergibt sie an die Channel-Rolle. Im Beispielprogramm spielte die ClientThread-Klasse diese Rolle.

Kanalrolle Die Channel-Rolle empfängt die Request-Rolle von der Client-Rolle und übergibt sie an die Worker-Rolle. Im Beispielprogramm spielte die Channel-Klasse diese Rolle.

Arbeiterrolle Die Worker-Rolle empfängt die Request-Rolle von der Channel-Rolle und führt die Arbeit aus. Holen Sie sich nach der Arbeit die nächste Anforderungsrolle. Im Beispielprogramm spielte die WorkerThread-Klasse diese Rolle.

Rolle anfordern Die Anforderungsrolle besteht darin, einen Job darzustellen. Die Anforderungsrolle enthält die zur Ausführung der Aufgabe erforderlichen Informationen. Im Beispielprogramm spielte die Request-Klasse diese Rolle.

Tipps zur Erweiterung Ihrer Gedanken

Erhöhter Durchsatz Im Gegensatz zum Thread-Per-Message-Muster hat das Worker-Thread-Muster eines der Themen ** Wiederverwendung von Threads und Recycling zur Steigerung des Durchsatzes **.

Kapazitätskontrolle Die Anzahl der Dienste, die gleichzeitig bereitgestellt werden können, wird als Kapazität bezeichnet. Die Anzahl der Arbeiterrollen kann frei bestimmt werden. Im Beispielprogramm sind dies die Argumentthreads, die dem Channel-Konstruktor übergeben werden. Je mehr Worker-Rollen Sie haben, desto mehr Arbeit können Sie parallel ausführen. Die Vorbereitung von mehr Worker-Rollen als die Anzahl der gleichzeitig angeforderten Jobs ist jedoch nutzlos und verbraucht mehr Ressourcen. Die Anzahl der Worker-Rollen muss nicht unbedingt beim Start festgelegt werden und kann dynamisch geändert werden. Die Channel-Rolle enthält die Request-Rolle. Wenn die Anzahl der Anforderungsrollen, die von der Channel-Rolle gehalten werden können, groß ist, kann der Unterschied in der Verarbeitungsgeschwindigkeit zwischen der Client-Rolle und der Worker-Rolle gefüllt (gepuffert) werden. Es wird jedoch viel Speicher benötigt, um die Anforderungsrolle zu halten. Sie können sehen, dass es hier einen ** Kompromiss zwischen Kapazität und Ressource ** gibt.

Trennung von Aufruf und Ausführung Bei einem normalen Methodenaufruf werden "Methodenaufruf" und "Methodenausführung" nacheinander ausgeführt. ** Bei einem normalen Methodenaufruf sind Aufruf und Ausführung untrennbar miteinander verbunden **. ** Worker-Thread-Muster und Thread-Per-Message-Muster trennen jedoch Methodenaufruf und -ausführung **. Der Aufruf einer Methode wird als Aufruf bezeichnet, und die Ausführung wird als Ausführung bezeichnet. ** Das Worker-Thread-Muster und das Thread-Per-Message-Muster trennen den Aufruf und die Ausführung einer Methode **. Dies hat die folgenden Vorzüge.

--Verteilte Verarbeitung Es wird einfacher, den aufzurufenden Computer und den auszuführenden Computer zu trennen.

Vielseitige Anforderungsrolle Wenn Sie beispielsweise eine Unterklasse der Request-Klasse erstellen und ihre Instanz an Channel übergeben, ruft WorkerThread die Ausführung für diese Instanz problemlos auf. Dies kann als Verwendung von ** Polymorphismus ** ausgedrückt werden. Da alle zur Ausführung der Arbeit erforderlichen Informationen in der Anforderungsrolle beschrieben sind, müssen die Channel-Rolle und die Worker-Rolle diese nicht ändern, auch wenn eine facettenreiche Anforderungsrolle erstellt und die Arbeitstypen erhöht werden. Selbst wenn die Anzahl der Arbeitstypen zunimmt, ruft die Worker-Rolle nur die Ausführungsmethode der Anforderungsrolle auf.


Beziehung Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multithreaded Edition) "(Teil 1) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multi-Thread-Edition) "(Teil 2) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multi-Thread-Edition) "(Teil 3) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multi-Thread-Edition) "(Teil 4) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multithreaded Edition) "(Teil 5) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multithread Edition) "(Teil 6) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multithread Edition) "(Teil 7) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multithreaded Edition) "(Teil 8) Zusammenfassung der in Java-Sprache erlernten Entwurfsmuster (Multithreaded Edition) "(Teil 9)

Recommended Posts

Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 10)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 7)
Zusammenfassung von "In Java gelernte Entwurfsmuster (Multithread Edition)" (Teil 3)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 9)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 6)
Zusammenfassung von "In Java gelernte Entwurfsmuster (Multithread Edition)" (Teil 4)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 5)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 2)
Zusammenfassung von "In Java-Sprache erlernte Entwurfsmuster (Multi-Thread-Edition)" (Teil 1)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 11)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 12)
Zusammenfassung von "In Java gelernten Entwurfsmustern (Multithread Edition)" (Teil 8)
[Java] Zusammenfassung der Entwurfsmuster
Ein kurzer Überblick über Java, das in Klasse 4 gelernt wurde
Zusammenfassung der Grundlagen der Java-Sprache
Ein kurzer Überblick über Java, das in Klasse 3 gelernt wurde
Ein kurzer Überblick über Java, das in Klasse 2 gelernt wurde
Ich las Hiroshi Yuki "Einführung in Designmuster, die in Java gelernt wurden" (SB Creative)
Java-Entwurfsmuster
Was ich in Java gelernt habe (Teil 2) Was sind Variablen?
Ein kurzer Überblick über Java, das im Unterricht gelernt wurde
Zusammenfassung dessen, was ich in Spring Batch gelernt habe
Probieren Sie Designmuster in C-Sprache aus! Erinnerungsmuster - merken wir uns die Speicher der Daten
[Java] Grundlegende Zusammenfassung von Java, die nicht von Progate abgedeckt wird ~ Teil 1 ~
Was ich in Java gelernt habe (Teil 3) Anweisung zur Ausführung von Anweisungen
Zusammenfassung der Implementierung von Standardargumenten in Java
Zusammenfassung der Java-Unterstützung 2018
Zusammenfassung des Java-Entwurfsmusters
Was ich in Java gelernt habe (Teil 4) Bedingte Verzweigung und Wiederholung
[Java] Grundlegende Zusammenfassung von Java, die nicht von Progate abgedeckt wird ~ Teil 2 ・ Liste ~
Road to Java Engineer Part2 Was für eine Sprache ist Java?
[Java11] Stream-Zusammenfassung - Vorteile von Stream -
[Java] Zusammenfassung der regulären Ausdrücke
[Java] Zusammenfassung der Operatoren (Operator)
Zusammenfassung der Java Math Klasse
[Java] Zusammenfassung der Steuerungssyntax
Java-Implementierung von Tri-Tree
Zusammenfassung der Java-Fehlerverarbeitung
[Java] Zusammenfassung der mathematischen Operationen
Was ich in Java gelernt habe (Teil 1) Java-Entwicklungsablauf und Überblick
Zusammenfassung von ORM "uroboroSQL", das in Enterprise Java verwendet werden kann
[Für Anfänger] Zusammenfassung des Java-Konstruktors
Zusammenfassung des Pakets [Java Silver Study]
Grundlegende Verwendung von Java Optionaler Teil 1
Thread-sicherer Prozess in Java-Sprache
AtCoder 400 Punkte Algorithmus Zusammenfassung (Java Edition)
Liste der in Java 9 hinzugefügten Mitglieder
Führen Sie eine Phrasenanalyse in Java 8 durch (Teil 2).
Liste der in Java 9 hinzugefügten Typen
Zusammenfassung der objektorientierten Programmierung mit Java
Implementierung einer ähnlichen Funktion in Java
Erstellen einer Phrasenanalyse in Java 8 (Teil 1)