JUC并发编程学习笔记(七)常用的辅助类
1.JUC并发编程学习笔记(二)Lock锁(重点)2.JUC并发编程学习笔记(一)认知进程和线程3.JUC并发编程学习笔记(三)生产者和消费者问题4.JUC并发编程学习笔记(四)8锁现象5.JUC并发编程学习(五)集合类不安全6.JUC并发编程学习笔记(六)Callable(简单)
7.JUC并发编程学习笔记(七)常用的辅助类
8.JUC并发编程学习笔记(八)读写锁9.JUC并发编程学习笔记(九)阻塞队列10.JUC并发编程学习笔记(十)线程池(重点)11.JUC并发编程学习(十一)四大函数式接口(必备)12.JUC并发编程学习笔记(十二)Stream流式计算13.JUC并发编程学习(十三)ForkJoin14.JUC并发编程学习笔记(十四)异步回调15.JUC并发编程学习笔记(十五)JMM16.JUC并发编程学习笔记(十七)彻底玩转单例模式17.JUC并发编程学习笔记(十九)原子引用18.JUC并发编程(终章)各种锁的理解19.JUC并发编程学习笔记(十六)Volatile20.JUC并发编程学习笔记(十八)深入理解CAS常用的辅助类
CountDownLatch
这是一个JUC计数器辅助类,计数器有加有减,这是减。
使用方法
package org.example.demo; import java.util.concurrent.CountDownLatch; //线程计数器 public class CountDownLatchDemo { public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(6);//总数为6,必须要执行任务时用 for (int i = 0; i < 6; i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName()+" go out"); countDownLatch.countDown();//总数减1 },String.valueOf(i)).start(); } try { countDownLatch.await();//等待总数变为0才会往下执行,相当于阻塞当前线程 } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("关门"); } }
使用前
可能会在所有人没出去之前关门
使用后
不在乎谁先出去,但是一定要总数等于0后才会关门
原理
countDownLatch.countDown();//总数减1
countDownLatch.await();//等待总数变为0才会往下执行,相当于阻塞当前线程
每次有线程调用countDown() 数量减一,假设计数器变为0,await()就会被唤醒,继续执行!
CyclicBarrier
有减法就有加法
使用方法略有不同,一是添加了达到数量后可以执行一个方法,二十await方法放在了线程的内部
package org.example.demo; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{ System.out.println("召唤神龙成功");//在达到数量后运行一个Runnable接口方法 }); for (int i = 1; i <= 7; i++) { //lambda表达式本质上还是new了一个类,所以无法直接拿到for循环中的变量i,需要通过一个临时变量final来作为一个中间变量来获取到i final int temp = i; new Thread(()->{ System.out.println(Thread.currentThread().getName()+":获取到了"+temp+"颗龙珠"); try { cyclicBarrier.await();//每次等待完成后往下执行,如果达不到数量会死在这 } catch (InterruptedException e) { throw new RuntimeException(e); } catch (BrokenBarrierException e) { throw new RuntimeException(e); } },String.valueOf(i)).start(); } } }
Semaphore
Semaphore:信号量
抢车位:6辆车3个车位,123占据了那么456就需要等待,当占据的车走后,那么等待的车就要进入该车位。
用于限流等操作
package org.example.demo; import java.sql.Time; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SemaphoreDemo { public static void main(String[] args) { // 线程数量:限流!让没有得到的等待释放 Semaphore sim = new Semaphore(3); for (int i = 0; i < 6; i++) { new Thread(()->{ //acquire 得到 //release 释放 try { sim.acquire(); System.out.println(Thread.currentThread().getName()+":抢到车位"); TimeUnit.SECONDS.sleep(2); System.out.println(Thread.currentThread().getName()+":离开车位"); } catch (InterruptedException e) { throw new RuntimeException(e); }finally {//所有需要关闭、释放的操作都放在finally中 sim.release(); } }).start(); } } }
sim.acquire();//得到
sim.release();//释放
作用:多个共享资源互斥的使用!并发限流,控制最大线程数!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构