JUC并发编程学习笔记(七)常用的辅助类

常用的辅助类

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();//释放

作用:多个共享资源互斥的使用!并发限流,控制最大线程数!

posted @   高同学,你好  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示