Java常用的并发工具类:CountDownLatch、CyclicBarrier、Semaphore、Exchanger
1、CountDownLatch 等待多线程完成
它的构造函数接收一个int参数作为计数器,想等待N个点,就传入N。
当调用CountDownLatch的countDown()方法时,N就会减1,直至减为0。
使用await()方法等待,当N的值变为0时,执行await的线程继续执行
2、CyclicBarrier 同步屏障(可以理解为可循环的屏障)
可循环使用的屏障,它要做的事情就是让一组线程到达屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会打开,所有被阻塞的线程才会继续执行;
默认构造方法接收一个int参数,表示屏障拦截的线程数,每个线程调用await方法告诉CyclicBarrier 已经达到屏障了,然后当前线程阻塞。
3、CountDownLatch VS CyclicBarrier
CountDownLatch的计数器只使用一次,而CyclicBarrier 的计数器可以Reset方法重置,重复使用
4、Semaphore 控制线程并发数的信号量
控制有限个线程使用资源。构造方法接收一个int参数N,表示最大并发量,每个线程使用资源前调用acquire()方法获取权限,使用完后调用release()方法释放权限;
Semaphore有一个构造函数,可以传入一个int型整数n,表示某段代码最多只有n个线程可以访问,如果超出了n,那么请等待,等到某个线程执行完毕这段代码块,下一个线程再进入
5、Exchanger线程间的数据交换
提供一个同步点,在这个同步点,两个线程可以交换彼此的数据
1、public class CountDownLatchTest {
static CountDownLatch c = new CountDownLatch(2);
static ExecutorService pool = Executors.newFixedThreadPool(2);
public static void main(String agrs[]){
pool.execute(new Runnable() {
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(3);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("This is A");
c.countDown();
}
});
pool.execute(new Runnable() {
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(3);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("This is B");
c.countDown();
}
});
try {
c.await();
}catch (InterruptedException e){
}
System.out.println("This is main");
}
}
2、public class CyclicBarrierTest{
static CyclicBarrier c = new CyclicBarrier(2);
static ExecutorService pool = Executors.newFixedThreadPool(2);
public static void main(String)args){
pool.execute(new Runnable(){
public void run(){
sysout("this is A");
try{
c.await();
sysout("this is AA");
}catch( Exception e){ e.printStackTrace(); }
}
});
pool.execute(new Runnable(){
public void run(){
sysout("this is B");
try{
c.await();
sysout("this is BB");
}catch( Exception e){ e.printStackTrace(); }
}
});
pool.shutdown();
}
}
5、public Class ExchangerTest{
private static final Exchanger<String> exgr = new Exchanger<String>();
private static ExecutorService pool= Executors.newFixedThreadPool(2);
public static void main(String[] args){
pool.execute(new Runnable(){
public void run(){
String A = "银行流水A";
try{
A = exgr.exchange(A);
sysout("A当前值:"+A);
}catch(InterruptedException e){ }
}
});
pool.execute(new Runnable(){
public void run(){
String B = "银行流水B";
try{
B = exgr.exchange(B);
sysout(" B当前值:"+B);
}catch(InterruptedException e){ }
}
});
pool.shutdown();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」