Maison > Java > javaDidacticiel > Analyse du code source CyclicBarrier en Java

Analyse du code source CyclicBarrier en Java

WBOY
Libérer: 2023-04-30 20:55:13
avant
1383 Les gens l'ont consulté

    CyclicBarrier Introduction

    Pour CountDownLatch, d'autres fils de discussion sont des joueurs de jeu, comme League of Legends, et le le fil principal est contrôle Le fil où le jeu commence. Avant que tous les joueurs ne soient prêts, le fil principal est en attente, ce qui signifie que le jeu ne peut pas démarrer. Lorsque tous les joueurs sont prêts, l'exécuteur d'action suivant est le fil conducteur qui démarre la partie.

    Pour CyclicBarrier, supposons qu'une entreprise souhaite que tous les employés mènent une activité de consolidation d'équipe. L'activité consiste à franchir trois obstacles. Le temps nécessaire à chaque personne pour franchir les obstacles est différent. Cependant, l’entreprise exige que chacun franchisse l’obstacle actuel avant de commencer à franchir l’obstacle suivant. Autrement dit, une fois que tout le monde a franchi le premier obstacle, il commence à franchir le deuxième obstacle, et ainsi de suite. De manière analogique, chaque employé est un « autre fil conducteur ». Le programme se termine lorsque tout le monde a surmonté tous les obstacles. Le fil de discussion principal est peut-être terminé depuis longtemps, nous n'avons donc pas à nous soucier du fil de discussion principal ici.

    Analyse du code source de CyclicBarrier

    Relation d'héritage de classe

    CyclicBarrier ne montre pas de quelle classe parent il hérite ni de quelle interface parent il implémente, tous les AQS et verrous réentrants Pas par héritage, mais par composition.

    public class CyclicBarrier {}
    ```  
    
    ### 类的内部类
    
    CyclicBarrier类存在一个内部类Generation,每一次使用的CycBarrier可以当成Generation的实例,其源代码如下
    
    ```java
    private static class Generation {
    boolean broken = false;
    }
    Copier après la connexion

    Description : La classe Generation a un attribut cassé, qui est utilisé pour indiquer si la barrière actuelle est endommagée.

    Attributs de la classe

    public class CyclicBarrier {
    
    /** The lock for guarding barrier entry */
    // 可重入锁
    private final ReentrantLock lock = new ReentrantLock();
    /** Condition to wait on until tripped */
    // 条件队列
    private final Condition trip = lock.newCondition();
    /** The number of parties */
    // 参与的线程数量
    private final int parties;
    /* The command to run when tripped */
    // 由最后一个进入 barrier 的线程执行的操作
    private final Runnable barrierCommand;
    /** The current generation */
    // 当前代
    private Generation generation = new Generation();
    // 正在等待进入屏障的线程数量
    private int count;
    }
    Copier après la connexion

    Description : Cet attribut a un objet ReentrantLock et un objet Condition, et l'objet Condition est basé sur AQS, donc en dernière analyse, la couche inférieure est toujours prise en charge par AQS.

    Constructeur de classe

    Constructeur de type CyclicBarrier(int, Runnable)

    public CyclicBarrier(int parties, Runnable barrierAction) {
    // 参与的线程数量小于等于0,抛出异常
    if (parties <= 0) throw new IllegalArgumentException();
    // 设置parties
    this.parties = parties;
    // 设置count
    this.count = parties;
    // 设置barrierCommand
    this.barrierCommand = barrierAction;
    }
    Copier après la connexion
    #🎜🎜 #

    Description : Ce constructeur peut spécifier le nombre de threads associés au CyclicBarrier et peut spécifier l'action d'exécution une fois que tous les threads entrent dans la barrière. L'action d'exécution est déterminée par le dernier thread qui exécute la barrière. . mettre en œuvre.

    Constructeur de type CyclicBarrier(int)

    public CyclicBarrier(int parties) {
    // 调用含有两个参数的构造函数
    this(parties, null);
    }
    Copier après la connexion

    Description : Ceci Le constructeur exécute uniquement le nombre de threads associés au CyclicBarrier et ne définit pas d'actions d'exécution.

    Fonction principale - fonction dowait

    Cette fonction est la fonction principale de la classe CyclicBarrier. La fonction d'attente fournie par la classe CyclicBarrier est appelée fonction doawait at. la couche inférieure,

    Le code source est le suivant :

    private int dowait(boolean timed, long nanos)
    throws InterruptedException, BrokenBarrierException,
    TimeoutException {
    // 保存当前锁
    final ReentrantLock lock = this.lock;
    // 锁定
    lock.lock();
    try {
    // 保存当前代
    final Generation g = generation;
    
    if (g.broken) // 屏障被破坏,抛出异常
    throw new BrokenBarrierException();
    
    if (Thread.interrupted()) { // 线程被中断
    // 损坏当前屏障,并且唤醒所有的线程,只有拥有锁的时候才会调用
    breakBarrier();
    // 抛出异常
    throw new InterruptedException();
    }
    
    // 减少正在等待进入屏障的线程数量
    int index = --count;
    if (index == 0) { // 正在等待进入屏障的线程数量为0,所有线程都已经进入
    // 运行的动作标识
    boolean ranAction = false;
    try {
    // 保存运行动作
    final Runnable command = barrierCommand;
    if (command != null) // 动作不为空
    // 运行
    command.run();
    // 设置ranAction状态
    ranAction = true;
    // 进入下一代
    nextGeneration();
    return 0;
    } finally {
    if (!ranAction) // 没有运行的动作
    // 损坏当前屏障
    breakBarrier();
    }
    }
    
    // loop until tripped, broken, interrupted, or timed out
    // 无限循环
    for (;;) {
    try {
    if (!timed) // 没有设置等待时间
    // 等待
    trip.await();
    else if (nanos > 0L) // 设置了等待时间,并且等待时间大于0
    // 等待指定时长
    nanos = trip.awaitNanos(nanos);
    } catch (InterruptedException ie) {
    if (g == generation && ! g.broken) { // 等于当前代并且屏障没有被损坏
    // 损坏当前屏障
    breakBarrier();
    // 抛出异常
    throw ie;
    } else { // 不等于当前带后者是屏障被损坏
    // We&#39;re about to finish waiting even if we had not
    // been interrupted, so this interrupt is deemed to
    // "belong" to subsequent execution.
    // 中断当前线程
    Thread.currentThread().interrupt();
    }
    }
    
    if (g.broken) // 屏障被损坏,抛出异常
    throw new BrokenBarrierException();
    
    if (g != generation) // 不等于当前代
    // 返回索引
    return index;
    
    if (timed && nanos <= 0L) { // 设置了等待时间,并且等待时间小于0
    // 损坏屏障
    breakBarrier();
    // 抛出异常
    throw new TimeoutException();
    }
    }
    } finally {
    // 释放锁
    lock.unlock();
    }
    }
    Copier après la connexion

    Fonction Core - fonction nextGeneration

    Cette fonction entre dans tous les threads Elle sera appelée après la barrière, c'est-à-dire que la version suivante est générée et tous les threads peuvent réintégrer la barrière

    Le code source est comme. suit :

    private void nextGeneration() {
    // signal completion of last generation
    // 唤醒所有线程
    trip.signalAll();
    // set up next generation
    // 恢复正在等待进入屏障的线程数量
    count = parties;
    // 新生一代
    generation = new Generation();
    }
    Copier après la connexion
    #🎜 🎜#Dans cette fonction, la méthode signalAll d'AQS est appelée, ce qui réveille tous les threads en attente. Si tous les threads attendent cette condition, réveillez tous les threads.

    Le code source est le suivant :

    public final void signalAll() {
    if (!isHeldExclusively()) // 不被当前线程独占,抛出异常
    throw new IllegalMonitorStateException();
    // 保存condition队列头节点
    Node first = firstWaiter;
    if (first != null) // 头节点不为空
    // 唤醒所有等待线程
    doSignalAll(first);
    }
    Copier après la connexion

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Étiquettes associées:
    source:yisu.com
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal