Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 10)

javathread.jpeg

Modèle de fil de travail

travailleur signifie «travailleur». Dans le modèle WorkerThread, les ** threads de travail ** se mettent au travail un par un et le traitent. S'il n'y a pas de travail, le thread de travail attend un nouveau travail. Le thread de travail est parfois appelé ** Thread d'arrière-plan **.

Prenons l'exemple suivant. Un thread de la classe ClientThread envoie une demande de travail à la classe Channel. Une instance de la classe Channel a cinq threads de travail. Le thread de travail attend une demande de travail. Lorsqu'une demande de travail arrive, le thread de travail reçoit une demande de travail de Channel et la traite. Lorsque le processus est terminé, le thread de travail retourne à Channel et attend la demande suivante.

(Voir ce manuel pour le code complet)

Main.java


public class Main { 
    public static void main(String[] args) { 
        Channel channel = new Channel(5);   //Créer 5 threads de travail
        channel.startWorkers(); //Démarrer un thread de travail
        new ClientThread("Alice", channel).start();  //Démarrer un thread pour faire une demande de travail
        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);  //Faire une demande d'emploi
                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(); //Va chercher un travail
            request.execute(); 
        } 
    } 
}

La classe Channel a un champ appelé requestQueue pour transmettre les demandes de travail. La méthode putRequest place une requête dans cette file d'attente et la méthode takeRequest la récupère. Ici, le modèle producteur-consommateur est utilisé. Le modèle Thread-Per-Message a engendré un nouveau thread à chaque fois qu'il a fait un travail. Toutefois, dans le modèle de thread de travail, ** les threads de travail exécutent le travail à plusieurs reprises, il n'est donc pas nécessaire de démarrer un nouveau thread. ** WorkerThread n'a qu'une instance de Channel pour obtenir une demande de travail, et ne sait rien du travail spécifique.

Personnage

Rôle du client Le rôle Client crée une demande de travail en tant que rôle Request et la transmet au rôle Channel. Dans l'exemple de programme, la classe ClientThread a joué ce rôle.

Rôle du canal Le rôle Channel reçoit le rôle Request du rôle Client et le transmet au rôle Worker. Dans l'exemple de programme, la classe Channel a joué ce rôle.

Rôle du travailleur Le rôle Worker reçoit le rôle Request du rôle Channel et exécute le travail. Après le travail, accédez au prochain rôle Request. Dans l'exemple de programme, la classe WorkerThread a joué ce rôle.

Demander un rôle Le rôle Request est de représenter un travail. Le rôle Request contient les informations nécessaires pour exécuter la tâche. Dans l'exemple de programme, la classe Request a joué ce rôle.

Conseils pour élargir vos pensées

Augmentation du débit Contrairement au modèle Thread-Per-Message, le modèle Worker Thread a l'un des thèmes de ** réutilisation des threads et de recyclage pour augmenter le débit **.

Contrôle de capacité La quantité de services qui peuvent être fournis en même temps est appelée capacité. Le nombre de rôles de travail peut être librement déterminé. Dans l'exemple de programme, il s'agit des threads d'argument donnés au constructeur Channel. Plus vous avez de rôles de travail, plus vous pouvez effectuer de travail en parallèle, mais préparer plus de rôles de travail que le nombre de travaux demandés en même temps est inutile et consomme plus de ressources. Le nombre de rôles de travail ne doit pas nécessairement être défini au démarrage et peut être modifié de manière dynamique. Le rôle Channel détient le rôle Request. Si le nombre de rôles de demande pouvant être détenus par le rôle de canal est important, la différence de vitesse de traitement entre le rôle de client et le rôle de travail peut être remplie (mise en mémoire tampon). Cependant, une grande quantité de mémoire est consommée pour contenir le rôle Request. Vous pouvez voir qu'il y a un ** compromis capacité-ressources ** ici.

Séparation de l'invocation et de l'exécution Lors d'un appel de méthode normal, "l'invocation de méthode" et "l'exécution de méthode" sont exécutées successivement. ** Dans un appel de méthode normal, l'invocation et l'exécution sont inséparables **. Cependant, ** les modèles de thread de travail et les modèles de thread par message séparent l'appel et l'exécution de la méthode **. L'appel d'une méthode est appelé invocation et l'exécution est appelée exécution. ** On peut dire que le modèle Worker Thread et le modèle Thread-Per-Message séparent l'appel et l'exécution d'une méthode **. Cela présente les avantages suivants.

--Contrôle de l'ordre d'exécution (ordonnancement) Vous pouvez hiérarchiser le rôle Request et contrôler l'ordre dans lequel le rôle Channgel passe le rôle Request au rôle Worker. C'est ce qu'on appelle la demande ** planification **.

--Annulable / Répétable Bien que l'appel ait été effectué, l'exécution peut réaliser une fonction appelée annulation.

--Traitement distribué Il devient plus facile de séparer l'ordinateur à appeler et l'ordinateur à exécuter.

Rôle de requête à multiples facettes Par exemple, si vous créez une sous-classe de la classe Request et passez son instance à Channel, WorkerThread appellera execute pour cette instance sans aucun problème. Cela peut être exprimé comme utilisant le ** polymorphisme **. Étant donné que toutes les informations nécessaires pour exécuter le travail sont décrites dans le rôle de demande, même si un rôle de demande à multiples facettes est créé et que les types de travail sont augmentés, le rôle de canal et le rôle de travailleur n'ont pas besoin de le modifier. Même si le nombre de types de travail augmente, le rôle Worker n'appelle toujours que la méthode d'exécution du rôle Request.


Relation Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 1) Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 2) Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 3) Résumé de «Modèles de conception appris en langage Java (édition multi-thread)» (Partie 4) Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 5) Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 6) Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 7) Résumé de «Modèles de conception appris en langage Java (édition multi-thread)» (Partie 8) Résumé de «Modèles de conception appris en langage Java (édition multi-thread)» (Partie 9)

Recommended Posts

Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 10)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 7)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 3)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 9)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 6)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 4)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (Partie 5)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 2)
Résumé de «Modèles de conception appris en langage Java (édition multi-thread)» (Partie 1)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 11)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 12)
Résumé de «Modèles de conception appris en langage Java (édition multithread)» (partie 8)
[Java] Résumé des modèles de conception
Un examen rapide de Java appris en classe part4
Résumé des bases du langage Java
Un examen rapide de Java appris en classe part3
Un examen rapide de Java appris en classe part2
J'ai lu Hiroshi Yuki "Introduction aux modèles de conception appris en langage Java" (SB Creative)
Modèles de conception Java
Ce que j'ai appris en Java (partie 2) Que sont les variables?
Un examen rapide de Java appris en classe
Résumé de ce que j'ai appris dans Spring Batch
Essayez les modèles de conception en langage C! Modèle de souvenir - mémorisons les souvenirs des données
[Java] Résumé de base de Java non couvert par Progate ~ Partie 1 ~
Ce que j'ai appris en Java (partie 3) Déclaration d'exécution des instructions
Résumé de la mise en œuvre des arguments par défaut en Java
Résumé du support Java 2018
Résumé du modèle de conception Java
Ce que j'ai appris en Java (partie 4) Branchement conditionnel et répétition
[Java] Résumé de base de Java non couvert par Progate ~ Partie 2 ・ Liste ~
Road to Java Engineer Part2 Quel type de langage est Java?
[Java11] Résumé du flux -Avantages du flux-
[Java] Résumé des expressions régulières
[Java] Résumé des opérateurs (opérateur)
Résumé de la classe Java Math
[Java] Résumé de la syntaxe de contrôle
Implémentation Java de tri-tree
Résumé du traitement des erreurs Java
[Java] Résumé des opérations mathématiques
Ce que j'ai appris en Java (partie 1) Flux de développement Java et présentation
Résumé de l'ORM "uroboroSQL" qui peut être utilisé dans le Java d'entreprise
[Pour les débutants] Résumé du constructeur java
Résumé du package [Java Silver Study]
Utilisation de base de Java Facultatif Partie 1
processus thread-safe en java
Résumé de l'algorithme AtCoder 400 points (édition Java)
Liste des membres ajoutés dans Java 9
Faire une analyse de phrase en Java 8 (partie 2)
Liste des types ajoutés dans Java 9
Résumé de la programmation orientée objet utilisant Java
Implémentation d'une fonction similaire en Java
Création d'une analyse de phrase dans Java 8 (partie 1)