首页 > 其他分享 >循环计数器/循环栅栏/循环屏障 CyclicBarrier

循环计数器/循环栅栏/循环屏障 CyclicBarrier

时间:2024-09-09 15:15:23浏览次数:1  
标签:Thread barrier System 计数器 循环 println new CyclicBarrier

CyclicBarrier

和 CountDownLatch 有点类似,主要区别是 CyclicBarrier 可以重用,常用方法如下:

CyclicBarrier barrier = new CyclicBarrier(3); // 表示条件为:要有 3 个线程达到屏障(未指定屏障动作)
barrier.await(); // 如果没有 3 个线程到达屏障,当前线程就阻塞,直到有 3 个线程达到才恢复

// 指定屏障动作
CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
    @Override
    public void run() {
        System.out.println("All parties have arrived at the barrier, let's continue.");
    }
});

await() 底层是让 state - 1,达到栅栏的线程数量足够时,state 会重置,这样来体现可重用的。CountDown 不会重置 state

如果要使用线程池,线程池数量要和 CyclicBarrier 计数器一致

用法示例1

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.TimeoutException;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        // 创建一个 CyclicBarrier,设定需要3个线程到达屏障
        CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                // 当 3 个线程到达屏障,执行屏障动作
                System.out.println("All threads have reached the barrier, resuming execution.");
            }
        });

        // 启动3个线程,它们都会到达屏障
        for (int i = 0; i < 3; i++) {
            new Thread(new Worker(barrier)).start();
        }
    }
}

class Worker implements Runnable {
    private CyclicBarrier barrier;

    public Worker(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting at the barrier.");
            barrier.await(); // 当前线程挂起了,下面这行不会打印,直到 3 个线程达到屏障,当前线程恢复运行
            System.out.println(Thread.currentThread().getName() + " has passed the barrier.");
        } catch (InterruptedException | BrokenBarrierException e) {
            Thread.currentThread().interrupt();
        }
    }
}

用法示例2

执行两次,第二次执行的时候没有重新创建 CyclicBarrier,体现可重用

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.TimeoutException;

public class CyclicBarrierReusableExample {
    public static void main(String[] args) {
        final int numberOfThreads = 3;
        final CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, new Runnable() {
            @Override
            public void run() {
                System.out.println("Barrier reached! All threads completed the phase.");
            }
        });

        Runnable task = () -> {
            try {
                System.out.println(Thread.currentThread().getName() + " is performing task.");
                Thread.sleep((long) (Math.random() * 1000));
                System.out.println(Thread.currentThread().getName() + " finished task and waiting at the barrier.");
                barrier.await();
                // Phase complete, proceed to the next phase
                System.out.println(Thread.currentThread().getName() + " moving to the next phase.");
            } catch (InterruptedException | BrokenBarrierException e) {
                Thread.currentThread().interrupt();
            }
        };

        // Launch threads for phase 1
        for (int i = 0; i < numberOfThreads; i++) {
            new Thread(task).start();
        }

        // Wait for all threads to complete phase 1 and then start phase 2
        try {
            Thread.sleep(2000); // Simulate some delay between phases
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        System.out.println("Starting next phase...");

        // Launch threads for phase 2, using the same barrier
        for (int i = 0; i < numberOfThreads; i++) {
            new Thread(task).start();
        }
    }
}

改成 CountDown,因为 CountDown 的计数器不会重置,所以要创建多个 CountDown

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.BrokenBarrierException;

public class CountDownLatchExample {
    public static void main(String[] args) {
        final int numberOfThreads = 3;

        // Define a task
        Runnable task = new Runnable() {
            private CountDownLatch latch;

            public Runnable withLatch(CountDownLatch latch) {
                this.latch = latch;
                return this;
            }

            @Override
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName() + " is performing task.");
                    // Simulate some work
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println(Thread.currentThread().getName() + " finished task and waiting at the latch.");
                    latch.await();  // Wait until the latch count reaches zero
                    // Phase complete, proceed to the next phase
                    System.out.println(Thread.currentThread().getName() + " moving to the next phase.");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        };

        // Method to start threads with a CountDownLatch
        void startPhase(int numberOfThreads) {
            CountDownLatch latch = new CountDownLatch(numberOfThreads);

            // Start threads
            for (int i = 0; i < numberOfThreads; i++) {
                new Thread(task.withLatch(latch)).start();
            }

            // Release the latch after all threads have started
            new Thread(() -> {
                try {
                    Thread.sleep(2000); // Simulate some delay before releasing the latch
                    System.out.println("Releasing the latch!");
                    latch.countDown();  // Count down the latch to zero
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }

        // Start phase 1
        startPhase(numberOfThreads);

        // Wait for some time before starting the next phase
        try {
            Thread.sleep(3000); // Simulate some delay between phases
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        System.out.println("Starting next phase...");

        // Start phase 2
        startPhase(numberOfThreads);
    }
}

标签:Thread,barrier,System,计数器,循环,println,new,CyclicBarrier
From: https://www.cnblogs.com/cyrushuang/p/18404621

相关文章

  • 【洛谷 P1996】约瑟夫问题 题解(数组+模拟+循环)
    约瑟夫问题题目描述个人围成一圈,从第一个人开始报数,数到的人出列,再由下一个人重新从开始报数,数到的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰名小朋友,而该题是全部出圈。输入......
  • C++学习笔记(曾经我看不懂的代码2:基于范围的for循环、auto使用、stl容器、template模
    不知不觉c++程序设计:标准库已经看了一大半了,学到了很多,很多曾经在网上和在书上看到却看不懂的代码,在看完标准库中的大半内容以后,都能大致的理清代码的含义。代码模板一:for(auto&a:arr)1、基于范围的for循环:a为迭代变量,arr为迭代范围,&表示引用。写一个例子:#include<ios......
  • 51nod 1050 循环数组最大子段和
    51nod1050循环数组最大子段和虽然是板子题,两种做法,我们先写一种,另一个咕咕。因为是循环,所以分为两种,中间的和两边的,中间的直接dp求最大,两边的转化一下就是总的数字和减去中间的最小数字和。#include<bits/stdc++.h>usingnamespacestd;#definelllonglonglla[500005]......
  • 【C++学习笔记】逻辑判断语句与循环语句(二)
    目录一、逻辑判断语句1.1ifelse语句1.2 switch语句1.3枚举类型二、循环语句2.1while循环2.2dowhile循环2.3for循环2.4break与continue关键字2.5goto语句一、逻辑判断语句1.1ifelse语句#include"iostream"usingnamespacestd;intmain(){......
  • 1-8Java循环结构
    Java循环结构顺序结构的程序语句只能被执行一次。如果您想要同样的操作执行多次,,就需要使用循环结构。Java中有三种主要的循环结构:while循环do…while循环for循环在Java5中引入了一种主要用于数组的增强型for循环。while循环while是最基本的循环,它的结构为:`while`......
  • c语言第五章循环1.0
    #define_CRT_SECURE_NO_WARNINGS循环结构例1.11到100求和#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>intmain(){   intsum=0;   for(inti=1;i<=100;i++){      sum=sum+i;   }   printf("%d",sum);   return......
  • C语言--选择结构、循环结构练习题
    1.考虑到多重循环对程序效率的影响,以下哪种实现效率较高?为什么?(a)循环次数大的放在外层,循环次数小的放在内层;(b)循环次数小的放在外层,循环次数大的放在内层;答:(b);因为循环次数小的放在外层,当cpu处理完内层循环后从缓冲区拿取外层循环数据的次数会减少,在cpu内处理数据的时间......
  • 数据结构基础讲解(三)——线性表之循环链表专项练习
    本文数据结构讲解参考书目:通过网盘分享的文件:数据结构 C语言版.pdf链接: https://pan.baidu.com/s/159y_QTbXqpMhNCNP_Fls9g?pwd=ze8e 提取码:ze8e数据结构基础讲解(二)——线性表之单链表专项练习-CSDN博客 个人主页:樱娆π-CSDN博客目录循环链表双向链表......
  • 【洛谷 P1996】约瑟夫问题 题解(队列+模拟+循环)
    约瑟夫问题题目描述个人围成一圈,从第一个人开始报数,数到的人出列,再由下一个人重新从开始报数,数到的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰名小朋友,而该题是全部出圈。输入......
  • Python循环语句
    1-While循环语法:变量=初始值while条件判断:循环体(要循环执行的代码)条件控制语句注意:如果条件恒成立或者直接写True,就会出现无限循环示例:#打印99次,“我爱你”#变量先定义再使用i=1whilei<100:print("我爱你")i+=1whileTrue:......