JUC当中的几个计数类

目录

CountDownLatch

原理

CyclicBarrier

Semaphore


CountDownLatch

官方文档解释:CountDownLatch是一种同步辅助工具,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。

CountDownLatch 使用给定的计数进行初始化。await 方法会阻塞,直到当前计数因 countDown() 方法的调用而减至零,此后所有等待的线程被释放,并且任何后续对 await 的调用都会立即返回。这是一次性现象------计数无法重置。如果需要可以重置计数的版本,请考虑使用 CyclicBarrier。

使用示例:

java 复制代码
import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "..........");
                countDownLatch.countDown(); //数量减一
            }, String.valueOf(i)).start();
        }
//        countDownLatch.await(); //等待计数器归零, 然后向下执行
        System.out.println("已经全部执行完成");
    }
}

如果不加上await方法的话,线程不会被阻塞,main线程往下执行,输出打印

如果加上了await方法的话,线程会等待计数器归零才会往下执行

原理

countDownLatch.countDown() //数量减一

countDownLatch.await() //等待计数器归零,然后向下执行

每次有线程调用countDown()数量-1,假设计数器变为0,countDownLatch.await()就会被唤醒,继续执行

CyclicBarrier

CyclicBarrier 是一种同步辅助工具,它允许一组线程互相等待,直到所有线程都到达一个共同的屏障点。CyclicBarrier 在涉及固定大小线程组的程序中非常有用,这些线程偶尔需要互相等待。这个屏障被称为"循环的",是因为它可以在等待的线程被释放后重复使用。 CyclicBarrier 支持一个可选的 Runnable 命令,该命令在每个屏障点执行一次------在组中最后一个线程到达屏障之后,但在任何线程被释放之前。这个屏障操作对于在任意线程继续执行之前更新共享状态非常有用。

通俗理解就是加法计数器

使用方法和CountDownLatch类似

java 复制代码
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
            System.out.println("达到5了.............");
        });

        //创建5个线程
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName());
                try {
                    cyclicBarrier.await(); // 等待
                } catch (InterruptedException | BrokenBarrierException e) {
                    throw new RuntimeException(e);
                }
            }, "Thread-" + i).start();
        }
    }
}

代码创建了一个CyclicBarrier屏障类,它会阻塞到达屏障的线程,然后在构造器里面传入了参数5,表示五个线程到达屏障之后就会释放所有线程,并且传入了一个Runnable线程打印结果

Semaphore

Semaphore 是一个计数信号量。从概念上讲,信号量维护着一组许可。每个 acquire() 方法在必要时会阻塞,直到有可用的许可,然后获取该许可。每个 release() 方法会添加一个许可,可能会释放一个正在阻塞的获取者。但是,并没有实际的许可对象被使用;Semaphore 只是维护可用数量的计数并相应地执行操作。

使用方法

java 复制代码
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreTest {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); //允许3个线程同时拥有资源
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire(); // 线程得到信号量
                    System.out.println(Thread.currentThread().getName() + "得到信号量......");
                    TimeUnit.SECONDS.sleep(5); //休眠两秒钟
                    System.out.println(Thread.currentThread().getName() + "释放信号量......");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }finally {
                    semaphore.release(); //释放信号量
                }
            }, String.valueOf(i)).start();
        }
    }
}

代码解释:

首先是某三个线程得到信号量,然后是休眠五秒钟后,执行finally代码块里面的release方法释放掉,随后空闲的三个信号量又被其他两个线程拿走(剩下了一个),休眠五秒钟后释放。

相关推荐
水月清辉1 小时前
利用python生成一个终极复杂动画:跳动小红心 ✨
开发语言·python
xdl25991 小时前
如何快速搭建简单SpringBoot项目网页
java·spring boot·intellij-idea
小菜鸡桃蛋狗1 小时前
C++——类和对象(中)
开发语言·c++
暮光6291 小时前
通过python启动参数配置ros参数
开发语言·python
k-l.2 小时前
【通过jdbc连接到kingbase数据库插入10w数据】
java·数据库
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 基于java的书店用户管理系统的设计与实现为例,包含答辩的问题和答案
java·开发语言
gis分享者2 小时前
华为OD面试-Java、C++、Pyhton等多语言实现-目录
java·c++·华为od·面试·目录·od·机试
kyle~2 小时前
C++--- dlsym 调用封装好的算法动态库的核心工具 <dlfcn.h>
开发语言·c++·算法
一晌小贪欢2 小时前
Python办公自动化指南:Pandas与Openpyxl的全面比较与选择
开发语言·python·pandas·python基础·python入门·python小白