Rumah > Java > javaTutorial > Analisis kod sumber CyclicBarrier dalam Java

Analisis kod sumber CyclicBarrier dalam Java

WBOY
Lepaskan: 2023-04-30 20:55:13
ke hadapan
1384 orang telah melayarinya

    Pengenalan kepada CyclicBarrier

    Untuk CountDownLatch, utas lain ialah pemain permainan, seperti League of Legends, dan utas utama ialah utas yang mengawal permulaan permainan. Sebelum semua pemain bersedia, utas utama berada dalam keadaan menunggu, yang bermaksud permainan tidak boleh dimulakan. Apabila semua pemain bersedia, pelaksana tindakan seterusnya ialah utas utama, yang memulakan permainan.

    Untuk CyclicBarrier, andaikan sebuah syarikat mahu semua pekerja menjalankan aktiviti membina pasukan Aktiviti ini melibatkan memanjat tiga halangan. Walau bagaimanapun, syarikat memerlukan semua orang untuk memanjat halangan semasa sebelum mula mendaki halangan seterusnya, iaitu, selepas semua orang memanjat halangan pertama, mereka mula mendaki halangan kedua, dan seterusnya. Secara analoginya, setiap pekerja adalah "benang lain". Program ini berakhir apabila semua orang telah mengatasi semua halangan. Utas utama mungkin sudah lama tamat, jadi kita tidak perlu risau tentang utas utama di sini.

    Analisis kod sumber CyclicBarrier

    Hubungan warisan kelas

    CyclicBarrier tidak menunjukkan kelas induk yang diwarisinya atau antara muka induk yang ia laksanakan. Semua kunci AQS dan reentrant tidak dilaksanakan warisan Ia dicapai melalui gabungan.

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

    Penjelasan: Kelas Generasi mempunyai atribut yang rosak, yang digunakan untuk menunjukkan sama ada halangan semasa rosak.

    Atribut kelas

    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;
    }
    Salin selepas log masuk

    Penjelasan: Atribut ini mempunyai satu objek ReentrantLock dan satu objek Condition, dan objek Condition adalah berdasarkan AQS , jadi, dalam analisis akhir, lapisan bawah masih disokong oleh AQS.

    Pembina kelas

    Pembina jenis 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;
    }
    Salin selepas log masuk

    Penerangan: Pembina ini boleh menentukan bilangan utas yang dikaitkan dengan CyclicBarrier, dan boleh menentukan tindakan pelaksanaan selepas semua utas memasuki halangan, yang dilaksanakan oleh utas terakhir untuk melaksanakan halangan.

    Pembina jenis CyclicBarrier(int)

    public CyclicBarrier(int parties) {
    // 调用含有两个参数的构造函数
    this(parties, null);
    }
    Salin selepas log masuk

    Nota: Pembina ini hanya melaksanakan fungsi yang dikaitkan dengan CyclicBarrier The bilangan utas, tiada tindakan pelaksanaan ditetapkan.

    Fungsi teras - fungsi dowait

    Fungsi ini ialah fungsi teras kelas CyclicBarrier Fungsi await yang disediakan oleh kelas CyclicBarrier memanggil fungsi doawait di lapisan bawah, <🎜. >

    Kod sumber adalah seperti berikut:

    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();
    }
    }
    Salin selepas log masuk

    Fungsi teras - fungsi nextGeneration

    Fungsi ini akan dipanggil selepas semua utas memasuki penghalang, iaitu, versi seterusnya dijana, semua Benang boleh memasuki semula penghalang

    Kod sumber adalah seperti berikut:

    private void nextGeneration() {
    // signal completion of last generation
    // 唤醒所有线程
    trip.signalAll();
    // set up next generation
    // 恢复正在等待进入屏障的线程数量
    count = parties;
    // 新生一代
    generation = new Generation();
    }
    Salin selepas log masuk

    Dalam fungsi ini, kaedah isyaratSemua. AQS akan dipanggil, yang membangunkan semua rangkaian menunggu. Jika semua utas sedang menunggu keadaan ini, bangunkan semua utas.

    Kod sumber adalah seperti berikut:

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

    Atas ialah kandungan terperinci Analisis kod sumber CyclicBarrier dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Label berkaitan:
    sumber:yisu.com
    Kenyataan Laman Web ini
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
    Tutorial Popular
    Lagi>
    Muat turun terkini
    Lagi>
    kesan web
    Kod sumber laman web
    Bahan laman web
    Templat hujung hadapan