JUC:三大辅助类

本文深入探讨了Java并发编程中三种核心同步工具:CountDownLatch, CyclicBarrier和Semaphore的工作原理及应用案例。CountDownLatch作为线程的减法计数器,用于一个线程等待其他线程完成任务。CyclicBarrier作为线程加分计数器,确保一组线程在达到特定点时同步等待。Semaphore则用于限流,通过控制资源的并发访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. CountDownLatch

允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。CountDownLatch用给定的计数初始化await方法阻塞,直到由于countDown()方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await 调用立即返回。 (理解成线程的减法计数器)

CountDownLatch是一种通用的同步工具,可用于多种用途。 一个CountDownLatch为一个计数的CountDownLatch用作一个简单的开/关锁存器,或者门:所有线程调用await在门口等待,直到被调用countDown()的线程打开。 一个CountDownLatch初始化N可以用来做一个线程等待,直到N个线程完成某项操作,或某些动作已经完成N次。

countDown
在这里插入图片描述
await
在这里插入图片描述

案例:

    CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"ThreadOut");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        countDownLatch.await();
        System.out.println("AllStop");
0ThreadOut
1ThreadOut
4ThreadOut
5ThreadOut
2ThreadOut
3ThreadOut
AllStop

不加 countDownLatch.await();

0ThreadOut
3ThreadOut
AllStop
1ThreadOut
2ThreadOut
5ThreadOut
4ThreadOut

2. CyclicBarrier

允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。 屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。 (理解成线程加分计数器)
CyclicBarrier支持一个可选的Runnable命令,每个屏障点运行一次,在parties中的最后一个线程到达之后,但在任何线程释放之前。 在任何一方继续进行之前,此屏障操作对更新共享状态很有用。

构造方法
在这里插入图片描述

await
在这里插入图片描述

案例:召唤神龙;当线程数累加到7时,才会达到结束堵塞条件,如果达不到则一直堵塞;

		// 召唤龙珠的线程
		CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
            System.out.println(Thread.currentThread().getName()+"召唤神龙");
        });
        for (int i = 1; i <= 7; i++) {
            final int tmp=i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"获取龙珠"+tmp);
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();

        }
Thread-1获取龙珠2
Thread-0获取龙珠1
Thread-4获取龙珠5
Thread-3获取龙珠4
Thread-2获取龙珠3
Thread-5获取龙珠6
Thread-6获取龙珠7
Thread-6召唤神龙

当parties数量大于等待线程的数量时候,就会死锁;

Thread-1获取龙珠2
Thread-2获取龙珠3
Thread-0获取龙珠1
Thread-3获取龙珠4
Thread-4获取龙珠5
Thread-6获取龙珠7
Thread-5获取龙珠6

3.Semaphore

一个计数信号量。 在概念上,信号量维持一组许可证。 在一个线程中通过acquire()获取一张通行证,release()方法释放该通行证。如果信号量中通行证剩余数量为0,则该线程堵塞,只有等待其他线程释放通行证才能使用。(限流的思想)

acquire方法
在这里插入图片描述
release
在这里插入图片描述

抢车位案例:六个线程(车)抢占3个信号量(车位)

		  //抢车位案例
		  //设置线程数量:车位限定3个(限流)
 		 Semaphore semaphore = new Semaphore(3);
        for (int i = 1; i < 6; i++) {
            final int tmp=i;
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"抢占车位"+tmp);
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName()+"离开车位"+tmp);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
2抢占车位2
3抢占车位3
1抢占车位1
1离开车位1
2离开车位2
3离开车位3
4抢占车位4
5抢占车位5
4离开车位4
5离开车位5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值