当前位置:网站首页>JUC总结
JUC总结
2022-07-26 13:16:00 【weixin_43766298】
java.util.concurrent
1. CyclicBarrier
- 可重复使用的屏障:当请求线程达到一定的数量才会放行,放行之后会再次重置待拦截的线程数量
- 代码示例
public static void testCyclicBarrier(){
CyclicBarrier cyclicBarrier =
new CyclicBarrier(4, () -> System.out.println(Thread.currentThread().getName()+":人满开始游戏!"));
class Task implements Runnable{
private CyclicBarrier cyclicBarrier;
public Task(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+":准备就绪");
cyclicBarrier.await();// 一进来就被阻塞并加入等待队列中
System.out.println(Thread.currentThread().getName()+":游戏中...");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
for (int i = 0; i < 8; i++) {
try {
TimeUnit.MILLISECONDS.sleep(500);// 增加间隔时间,让效果更加直观清晰
new Thread(new Task(cyclicBarrier),"线程_"+i).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 控制台输出
线程_0:准备就绪
线程_1:准备就绪
线程_2:准备就绪
线程_3:准备就绪
线程_3:人满开始游戏!
线程_3:游戏中...
线程_0:游戏中...
线程_1:游戏中...
线程_2:游戏中...
线程_4:准备就绪
线程_5:准备就绪
线程_6:准备就绪
线程_7:准备就绪
线程_7:人满开始游戏!
线程_7:游戏中...
线程_4:游戏中...
线程_5:游戏中...
线程_6:游戏中...
2. Semaphore
- Semaphore 就是一个信号量,它的作用是单机应用限流,限制某个接口的并发数
- Semaphore的剩余许可量是通过AQS中的state属性进行的记录,获取许可是将该值进行减少,释放许可是将该值进行增加,当没有足够的许可时,线程会加入到阻塞队列中等待其他线程释放许可并唤醒。
- 代码示例
public static void testSemaphore(){
Semaphore semaphore = new Semaphore(3);
class RUN implements Runnable{
private Semaphore semaphore;
public RUN(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
try {
System.out.println("剩余许可证:" + semaphore.availablePermits());
semaphore.acquire();// 许可不足的话,当前线程就会被阻塞并且加入等待队列,直到有一个可用的许可证为止,就会被唤醒
System.out.println(threadName + ":获取到许可证,执行任务");
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(threadName + ":完成任务,释放许可证");
semaphore.release();
}
}
}
for (int i = 0; i < 12; i++) {
new Thread(new RUN(semaphore),"线程"+i).start();
}
}
- 控制台输出
剩余许可证:3
线程0:获取到许可证,执行任务
剩余许可证:2
线程3:获取到许可证,执行任务
剩余许可证:1
线程4:获取到许可证,执行任务
剩余许可证:0
剩余许可证:0
剩余许可证:0
剩余许可证:0
剩余许可证:0
剩余许可证:0
剩余许可证:0
剩余许可证:0
剩余许可证:0
线程3:完成任务,释放许可证
线程0:完成任务,释放许可证
线程7:获取到许可证,执行任务
线程8:获取到许可证,执行任务
线程4:完成任务,释放许可证
线程11:获取到许可证,执行任务
线程7:完成任务,释放许可证
线程11:完成任务,释放许可证
线程1:获取到许可证,执行任务
线程8:完成任务,释放许可证
线程2:获取到许可证,执行任务
线程5:获取到许可证,执行任务
线程2:完成任务,释放许可证
线程1:完成任务,释放许可证
线程5:完成任务,释放许可证
线程9:获取到许可证,执行任务
线程6:获取到许可证,执行任务
线程10:获取到许可证,执行任务
线程6:完成任务,释放许可证
线程9:完成任务,释放许可证
线程10:完成任务,释放许可证
3. CountDownLatch
- CountDownLatch 翻译过来就是倒数的门锁,可以理解为 计数器屏障
- CountDownLatch 的使用场景一:主线程等待,多个子线程完成任务后,进行汇总合并。
// 主线程等待,多个子线程(任务)完成后,进行汇总合并
public static void testCountDownLatch() throws InterruptedException {
long start = System.currentTimeMillis();
CountDownLatch countDownLatch = new CountDownLatch(5);
class RUN implements Runnable{
private CountDownLatch latch;
public RUN(CountDownLatch latch){
this.latch = latch;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"_开始执行");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
//
}
} finally {
System.out.println(Thread.currentThread().getName()+"_执行完毕,准备对计数器进行 减1操作");
latch.countDown();// 使用CAS 对 AQS的volatile state属性进行-1操作
}
}
}
for (int i = 0; i < 5; i++) {
new Thread(new RUN(countDownLatch)).start();
}
System.out.println("...主线程准备等待...");
// 主线程等待,当计数器state==0,就唤醒主线程往下执行,可设置最大等待时间。
countDownLatch.await();
System.out.println("...主线程完成等待...");
System.out.println("总花费时间__" + (System.currentTimeMillis()-start));
}
...主线程准备等待...
Thread-0_开始执行
Thread-2_开始执行
Thread-3_开始执行
Thread-1_开始执行
Thread-4_开始执行
Thread-0_执行完毕,准备对计数器进行 减1操作
Thread-1_执行完毕,准备对计数器进行 减1操作
Thread-4_执行完毕,准备对计数器进行 减1操作
Thread-3_执行完毕,准备对计数器进行 减1操作
Thread-2_执行完毕,准备对计数器进行 减1操作
...主线程完成等待...
总花费时间__2030
- CountDownLatch 的使用场景二:多个线程等待:模拟并发,请求一进来就被阻塞,让线程一起执行
// 多个线程等待:模拟并发,请求一进来就被阻塞,让并发线程一起执行
public static void testCountDownLatch2() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
class RUN implements Runnable{
private CountDownLatch latch;
public RUN(CountDownLatch latch){
this.latch = latch;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"_阻塞等待");
latch.await();//所有请求都阻塞在这,等待
System.out.println(Thread.currentThread().getName()+"_开始执行");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+"_执行完毕");
} catch (Exception e){
e.printStackTrace();
}
}
}
for (int i = 0; i < 4; i++) {
new Thread(new RUN(countDownLatch),"线程"+i).start();
}
TimeUnit.SECONDS.sleep(5); // 主线程休眠 让 子线程请求都准备好
System.out.println("MAIN 线程 使得计数减1... 唤醒所有子线程...");
countDownLatch.countDown();// 主线程休眠后 调用countDown() 是计数器减1 所有的子线程将会被放行
}
线程2_阻塞等待
线程3_阻塞等待
线程0_阻塞等待
线程1_阻塞等待
MAIN 线程 使得计数减1... 唤醒所有子线程...
线程2_开始执行
线程1_开始执行
线程0_开始执行
线程3_开始执行
线程1_执行完毕
线程2_执行完毕
线程0_执行完毕
线程3_执行完毕
边栏推荐
- 基于WebRTC和WebSocket实现的聊天系统
- 1312_适用7z命令进行压缩与解压
- Some practical operations of vector
- Can I take your subdomain? Exploring Same-Site Attacks in the Modern Web
- 【花雕动手做】有趣好玩的音乐可视化系列小项目(12)---米管快速节奏灯
- 概要设计说明书
- Square root of leetcode 69. x
- The difference between $route and $route
- MySQL data directory (3) -- table data structure MyISAM (XXVI)
- From January to June, China's ADAS suppliers accounted for 9%, and another parts giant comprehensively laid out the new smart drive track
猜你喜欢

Shutter background graying effect, how transparency, gray mask

From January to June, China's ADAS suppliers accounted for 9%, and another parts giant comprehensively laid out the new smart drive track

Student examination system based on C #

1312_ Apply 7z command for compression and decompression

Can I take your subdomain? Exploring Same-Site Attacks in the Modern Web

Qualcomm once again "bet" on Zhongke Chuangda to challenge the full stack solution of intelligent driving software and hardware

Kubelet CRI container runtime

Hcip day 12 notes sorting (BGP Federation, routing rules)

解决方案丨5G技术助力搭建智慧园区

postgresql官网下载出错
随机推荐
多线程使用不当导致的 OOM
B+树(3)聚簇索引,二级索引 --mysql从入门到精通(十五)
After being fined "paid leave" for one month, Google fired him who "loves" AI
C regards type as generic type T and uses it as generic type of method
Guys, please ask me, I have configured CDC to connect to Oracle according to the document, and I always run error reports and can't find the class validstione
[typescript] typescript common types (Part 2)
一笔画问题(中国邮递员问题)
Research status and pain points of deep learning 3D human posture estimation at home and abroad
1312_适用7z命令进行压缩与解压
概要设计说明书
B+ tree index use (9) grouping, back to table, overlay index (21)
同花顺开的账户安全吗?
[flower carving hands-on] fun music visualization series small project (12) -- meter tube fast rhythm light
Extra (5) - MySQL execution plan (51)
终极套娃 2.0 | 云原生交付的封装
Flutter integrated Aurora push
MySQL data directory (1) -- database structure (24)
B+树(5)myISAM简介 --mysql从入门到精通(十七)
3D modeling and rendering based on B é zier curve
Kubernetes apiserver current limiting strategy