JUC下countDownLatch、CyclicBarrier、Semaphore以及枚举的常见使用方法
1.Java_第一季_JAVASE_自增、单例模式、类与实例初始化过程、方法参数传递机制、递归和迭代、成员变量与局部变量2.Java_第一季_SSM_Spring Bean的作用域、Spring事务的传播行为、Spring MVC的执行流程、3.Java_第一季_java高级_Redis持久化、MySql何时建立索引4.java_JUC、volatile5.java_CAS6.java_阻塞队列(FIFO先进先出)
7.JUC下countDownLatch、CyclicBarrier、Semaphore以及枚举的常见使用方法
8.java_锁9.java_集合不安全10.Spring循环依赖11.AbstractQueuedSynchronizer---AQS12.LockSuport13.java_线程池7大参数_底层运行原理14.java_线程池三个常用方式15.Java_Callable<V>的基本使用16.java_锁_synchronized与Lock的区别17.java_强、软、弱、虚四大引用18.java_OOM19.JAVA-interview20.java_NIO21.java_JVM之GC22.java_JVM23.单例模式设计24.netty服务端、客户端简单搭建25.java使用webSocket与前端通讯26.java串口通讯27.用Java读取文件文字并语音播报28.Proguard-混淆29.Spring Security30.MQ31.spring相关面试题32.执行jar包33.Spring34.SpringBoot数据访问35.Java Stream(流)基本使用36.java集合工具类 Collections基本使用37.LocalDateTime、LocalDate、Date、String相互转化38.java8新特性39.java设计模式40.java springboot使用定时器41.MQ根据正常队列、死信队列来实现延迟队列的场景枚举类
@Getter public enum CountryEnum { ONE(1, "燕"), TWO(2,"赵"), THREE(3,"韩"), FOUR(4,"魏"), FIVE(5,"齐"), SIX(6,"楚"); private Integer code; private String mess; CountryEnum(Integer code, String mess) { this.code = code; this.mess = mess; } public static CountryEnum forEachCountryEnum(int index){ CountryEnum[] values = CountryEnum.values(); for (CountryEnum e : values) { if (index == e.getCode()){ return e; } } return null; } }
1、countDownLatch
countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap、BlockingQueue。
存在于java.util.cucurrent包下。
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
是通过一个计数器来实现的,计数器的初始值是线程的数量。
每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,
然后在闭锁上等待的线程就可以恢复工作了。
即:当一个或多个线程调用await()方法时,调用线程会被阻塞,其它线调用countDown()会将计数器减1(调用countDown()方法的线程不会被阻塞),
当计算器的值变为0时,因调用await()方法被阻塞的线程会被唤醒,继续执行;
代码示例:(未使用countDownLatch类)
public class CountDownLatchDemo { public static void main(String[] args) throws Exception { for (int i = 1; i <= 6; i++) { new Thread(() ->{ System.out.println(Thread.currentThread().getName()+"\t国:被灭;"); },CountryEnum.forEachCountryEnum(i).getMess()).start(); } System.out.println(Thread.currentThread().getName()+"\t***大秦帝国一统华夏***"); } }
代码示例:(使用countDownLatch类)
public class CountDownLatchDemo { public static void main(String[] args) throws Exception { CountDownLatch countDownLatch = new CountDownLatch(6);//初始值 6个线程 for (int i = 1; i <= 6; i++) { new Thread(() ->{ System.out.println(Thread.currentThread().getName()+"\t国:被灭;"); countDownLatch.countDown();//线程数 -1 },CountryEnum.forEachCountryEnum(i).getMess()).start(); } countDownLatch.await();//main线程等待,当countDownLatch值为0时放开; System.out.println(Thread.currentThread().getName()+"\t***大秦帝国一统华夏***"); } }
2、CyclicBarrier
CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。他要做的事情是让一组线程到达一个屏障(也可以叫同步点)时被阻塞;
直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截下来的线程才会继续执行,线程进入屏障通过CyclicBarrier的await()方法;
public class CyclicBarrierDemo { //CyclicBarrier(int parties) //创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待它时,它将跳闸,并且当屏障跳闸时不执行预定义的动作。 //CyclicBarrier(int parties, Runnable barrierAction) //创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行。 public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> { System.out.println("***召唤神龙***"); }); for (int i = 1; i <= 7; i++) { final int finalI = i; new Thread(() -> { System.out.println(Thread.currentThread().getName() + "\t 收集到第:" + finalI + "颗龙珠"); try { cyclicBarrier.await();//阻塞等待 } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } } }
3、Semaphore
信号量主要用于两个目的,一个用于多个共享资源的互斥作用,另一个用于并发线程数的控制;
Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。
使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。
/** * public Semaphore(int permits)创建一个 Semaphore与给定数量的许可证和非公平公平设置。 * 参数 * permits - permits的初始许可证。 该值可能为负数,在这种情况下,必须在任何获取被授予之前发布释放。 * <p> * public Semaphore(int permits,boolean fair)创建一个 Semaphore与给定数量的许可证和给定的公平设置。 * 参数 * permits - permits的初始许可证。 该值可能为负数,在这种情况下,必须在任何获取被授予之前发布释放。 * fair - true如果这个信号量将保证首先在竞争中首先授予许可证,否则 false */ public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3);//模拟三个停车位 for (int i = 1; i <= 6; i++) {//模拟6部车 new Thread(() -> { try { semaphore.acquire();//从该信号量获取许可证,阻止直到可用,或线程为 interrupted(被中断) 。 System.out.println(Thread.currentThread().getName() + "\t抢到车位"); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName() + "\t停车3秒后离开车位"); } catch (Exception e) { e.printStackTrace(); } finally { semaphore.release();//释放许可证,将其返回到信号量。 } }, String.valueOf(i)).start(); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?