des composants de base d'apprentissage netty (EventLoop, EventLoopGroup)

A, EventLoop, EventLoopGroup Vue d'ensemble

  Comme le montre la figure ci-dessous, NioEventLop EventLoop est une implémentation spécifique d'un EventLoopGroup d'attribut de EventLoop, NioEventLoopGroup est la réalisation de EventLoopGroup, Enfilez Pool Manager sont basées ExecutorService effectuée, de sorte que le rôle central EventLoop, EventLoopGroup est réalisé l'assemblage du sélecteur l'entretien et la piscine de fil d'entretien.

  

  Sélecteur de maintien est effectuée, dans lequel EventLoop, en bas à gauche, groupe de fils EventLoopGroup pour la maintenance, le contrôle de concurrence, le traitement des tâches, comme la droite sur la figure.

    

   A propos EventLoop et les relations de cartographie EventLoopGroup comme suit:

  • Un EventLoopGroup contient un ou plusieurs EventLoop;
  • Enfilez une EventLoop et une fixation que dans son cycle de vie;
  • Tous les traités EventLoop événements E / S sont traitées sur le fil de son propriétaire;
  • Un canal dans son cycle de vie ne sera enregistré dans un EventLoop;
  • Un EventLoop peut être affecté à un ou plusieurs de la Manche.

  Canal opération réseau Netty est une classe abstraite, EventLoop canal principalement pour le traitement des opérations d'E / S, avec la participation des deux opérations d'E / S. Lorsqu'une connexion arrive, Netty enregistrera un canal, puis attribuer un EventLoop lié à la chaîne de EventLoopGroup, le cycle de vie de la Manche sont liés EventLoop d'avoir ce service.

Deux, NioEventLoopGroup atteindre

  objets NioEventLoopGroup peuvent être compris comme un pool de threads, pour maintenir un ensemble de fils internes, chaque responsable de la gestion de plusieurs événements sur le canal et un canal ne correspond qu'à un fil, de sorte que vous pouvez éviter les problèmes de synchronisation des données sous plusieurs threads. Le code suivant

     // applications côté serveur à l' aide de deux NioEventLoopGroup créer deux groupes EventLoop, EventLoop Ceci est équivalent à un fil de traitement est Netty réception d' une demande de traitement des fils et des demandes d' entrées - sorties.
        // principal groupe de threads, pour accepter une connexion client, mais aucun traitement, tout comme le patron, ne pas faire les choses 
        EventLoopGroup bossGroup = new new NioEventLoopGroup ();
         // groupe de threads, quand le patron accepte la connexion et la connexion à l'enregistrement accepté travailleur, la liaison d'écoulement de traitement est acceptée. 
        WorkerGroup = EventLoopGroup nouvelle nouvelle NioEventLoopGroup ();

  其职责如下:

  • Comme le serveur  Acceptor 线程est responsable du traitement des demandes d' accès au client.
  • En tant que client  Connector 线程, le moniteur de connexion est responsable de l' enregistrement position de fonctionnement, le résultat de la détermination de la connexion asynchrone.
  • Comme  IO 线程, en écoutant le réseau lu peu, responsable de la lecture SocketChannel son message.
  • Comme le  IO fil est responsable de message écrit SocketChannel envoyé à l'autre partie, d'écrire un demi - paquet se passe, sera automatiquement enregistré pour écrire un écouteur d'événements pour la moitié après un paquet continue d'envoyer des données jusqu'à ce que toute la transmission de données est terminée.
  • Comme 定时任务线程, les tâches planifiées peuvent être effectuées, par exemple, le lien de détection est inactif et envoie un message de rythme cardiaque ou similaire.
  • En tant que thread d'exécution peut exécuter des fils de tâches communes (Exécutables).

  Le code ci-dessus lors de la création bossGroup et workerGroup, utilisez le constructeur sans argument NioEventLoopGroup, donc nous regardons la réalisation concrète NioEventLoopGroup:

    / ** 
     * 1, nous avons d' abord consulter le constructeur NioEventLoopGroup sans argument: 
     * Fonction: le nombre de threads est 0 
     * / 
    publique NioEventLoopGroup () {
         la présente (0 ); 
    } 

    / ** 
     * 2, continuent d'appeler le constructeur. 
     * Fonction: Indique le fil 0 et Executor est nulle 
     * / 
    publique NioEventLoopGroup ( int nThreads) {
         la présente (nThreads, (Exécuteur) null ); 
    } 

    / ** 
     * 3, continuer à appeler le constructeur. 
     * Fonction: Ce constructeur il sélecteur classe auxiliaire désigné "SelectorProvider.provider ()" 
     * / 
    publique NioEventLoopGroup ( int nThreads, l'Executor Executor) {
         la présente(NThreads, Exécuteur, SelectorProvider.provider ()); 
    } 

    / ** 
     * 4, continuer à appeler le constructeur. 
     * Fonction: initialise une politique de sélection par défaut, la politique pour générer un select 
     * / 
    publique NioEventLoopGroup ( int nThreads, l'Executor Executor , finale SelectorProvider SelectorProvider) {
         la présente (nThreads, exécuteur, SelectorProvider, DefaultSelectStrategyFactory.INSTANCE); 
    } 

    / ** 
     * 5, ont continué à appeler le constructeur. 
     * fonction: Indique la politique de rejet: RejectedExecutionHandlers.reject () 
     * / 
    publics NioEventLoopGroup ( int nThreads, Executor Executor, finale SelectorProvider SelectorProvider, finaleSelectStrategyFactory selectStrategyFactory) {
         super (nThreads, exécuteur testamentaire, selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject ()); 
    }

  Après une série de l'appel du constructeur ci-dessus, cette fois correspond aux paramètres suivants:

  • nThreads: 0
  • exécuteur: null
  • selectorProvider: SelectorProvider.provider ()
  • selectStrategyFactory: DefaultSelectStrategyFactory.INSTANCE
  • Et de préciser la stratégie de refus: RejectedExecutionHandlers.reject ()

  Continuer d'analyser les autres codes:

    / ** 
     * 6, d'appeler ici le constructeur de la superclasse MultithreadEventLoopGroup 
     * effet: qui est, lorsque le nombre spécifié de threads est 0, le nombre de threads par défaut DEFAULT_EVENT_LOOP_THREADS, 
     * et DEFAULT_EVENT_LOOP_THREAD est exécuté dans le bloc statique. 
     * / 
    Protégé MultithreadEventLoopGroup ( int nThreads, l'Executor Executor, ... args Object) {
         super (== 0 de nThreads? DEFAULT_EVENT_LOOP_THREADS: nThreads, Executor, args); 
    } 

    / ** 
     * 6.1 nous regardons bloc statique code 
     * rôle: cette étape les résultats point crucial: `Si le nombre de threads pour initialiser NioEventLoopGroup non spécifié, la valeur par défaut est le nombre de cœurs CPU * 2`. 
     * / 
    Privé  statique  final  int DEFAULT_EVENT_LOOP_THREADS; 

    statiques { 
        DEFAULT_EVENT_LOOP_THREADS(. 1 Math.max = , SystemPropertyUtil.getInt (
                 "io.netty.eventLoopThreads", NettyRuntime.availableProcessors () * 2 )) 
    } 

    / ** 
     . * 7, continuer à appeler le constructeur de la classe parent MultithreadEventLoopGroup 
     * Fonction: EventExecutor d'un spécifié plante sélection DefaultEventExecutorChooserFactory, 
     * cette plante est principalement utilisé pour sélectionner la prochaine EventExecutor disponible 
     * / 
    protégé MultithreadEventExecutorGroup ( int nThreads, l'Executor Executor, ... args Object) {
         les ce (nThreads, exécuteur, DefaultEventExecutorChooserFactory.INSTANCE, args); 
    } 

    / ** 
     * 8, continuer à appeler le constructeur de la classe parent MultithreadEventLoopGroup c'est le code de base pour supprimer un code non-core est 
     * le rôle d'une analyse séparée 
     * /
    protégées MultithreadEventExecutorGroup ( int nThreads, exécuteur testamentaire Exécuteur, EventExecutorChooserFactory chooserFactory, objet ... args) { 

        // 1,
         // vérification de l' exécuteur est vide pas, si vous créez ThreadPerTaskExecutor est vide, qui implémente l'interface Executor
         // Cet exécuteur est pour effectuer tous les fils dans la piscine de fil, qui est tout NioEventLoop, en fait, de
         // peut savoir constructeur NioEventLoop, constructeur NioEventLoop ont passé l'exécuteur de ce paramètre. 
        IF (exécuteur == NULL ) { 
            Executor = new new ThreadPerTaskExecutor (newDefaultThreadFactory ()); 
        } 

        // 2,
         // tableau enfants ici, en fait, le noyau mise en oeuvre de la piscine de fil, les fils de la piscine de fil est réalisé par un réseau de fil spécifié piscine;
         //Chaque élément du tableau est en fait un EventLoop, EventLoop est un EventExecutor sous-interface. 
        = Enfants new new EventExecutor [nThreads]; 

        // par exemple boucle du tableau enfants, NioEventLoop objets 
        pour ( int i = 0; I <nThreads; I ++ ) {
             Boolean succès = false ; 

            // . 3,
             // newChild (Exécuteur, args) fonctions NioEventLoopGroup mises en œuvre dans la classe,
             // essence est déposée dans une instance de classe NIOEventLoop 
            enfants [I] = newChild (exécuteur testamentaire, args); 
            succès = true ; 
        } 

        // 4, exemples de réalisation d' un sélecteur d'usine de fil.: les enfants de sélection Get
        = Chooser chooserFactory.newChooser (enfants); 

        // . 5, a été ajouté pour terminer le fil pour chaque thread d'écoute EventLoop 
        final FutureListener <Object> = terminationListener new new FutureListener <Object> () { 
            @Override 
            publique  vide operationComplete (Future <Object> Future) jette Exception {
                 IF (terminatedChildren.incrementAndGet () == children.length) { 
                    terminationFuture.setSuccess ( null ); 
                } 
            } 
        }; 

        // . 6, ajouter les enfants à l'ensemble correspondant au poids ensemble, représente en lecture seule.
        SET <EventExecutor> = childrenSet nouvelle nouvelle un LinkedHashSet <EventExecutor> (children.length); 
        Collections.addAll (childrenSet, enfants); 
        readonlyChildren = Collections.unmodifiableSet (childrenSet); 
    } 
} 

/ ** 
 * 8.3.1 nous regardons le newChild ( exécuteur testamentaire, args) dans la méthode 
 * nous pouvons voir est le retour d'un NioEventLoop 
 * / 
@Override 
protégé EventLoop newChild (executor executor, Object ... args) lancers francs Exception {
     retour  nouvelle nouvelle NioEventLoop ( la présente , exécuteur, (SelectorProvider) args [ 0 ], 
            ((SelectStrategyFactory) args [1]) newSelectStrategy (), (RejectedExecutionHandler) args [2. ]); 
}

  Résumant ce qui précède:

1. NioEventLoopGroup non spécifié lors de l' initialisation du nombre de fils, les fils vont utiliser le numéro par défaut, à savoir ` threads = noyaux CPU * 2 « ;
 2 . Chaque objet dispose d' un ensemble de NioEventLoopGroup interne executable` `de réseau NioEventLoop, dont la taille est nThreads, cela constitue un pool de threads , ` une réalisation compréhensible NIOEventLoop est un fil .
3 . NIOEventLoop toutes les discussions utilisant le même exécuteur, SelectorProvider, SelectStrategyFactory, RejectedExecutionHandler et appartenant à une certaine 
    NIOEventLoopGroup de. Ceci est de newChild (exécuteur testamentaire, args); méthode peut être vu: newChild mettre en œuvre () est mis en œuvre dans le NIOEventLoopGroup. 
4 . Lorsque des événements IO, vous devez sélectionner à partir d' un fil de pool de threads de l'exécution , cette fois la politique de sélection NioEventLoop est mis en œuvre par le GenericEventExecutorChooser et appeler cette classe carrée suivante () méthode.
5. Chaque objet dispose d' un sélecteur correspondant NioEventLoop NioEventLoopGroup, qui sera basée sur le nombre de NioEventLoop sélectionner dynamiquement Sélecteur (si une puissance de fonctionnement au niveau du bit 2, sinon le scrutin normal)

  En résumé, la fonction principale de résultats est de créer un certain nombre de NioEventLoop, mais l'accent réel NioEventLoop, il est la clé de tout fil Netty d'exécution.

Je suppose que tu aimes

Origine www.cnblogs.com/jing99/p/12515157.html
conseillé
Classement