论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
程序人生
›
5.5. Java并发工具类(如CountDownLatch、CyclicBarrier ...
5.5. Java并发工具类(如CountDownLatch、CyclicBarrier等)
守听
金牌会员
|
2023-6-1 00:42:41
|
显示全部楼层
|
阅读模式
楼主
主题
871
|
帖子
871
|
积分
2613
5.5.1 CountDownLatch
CountDownLatch是一个同步辅助类,它允许一个或多个线程等待,直到其他线程完成一组操作。CountDownLatch有一个计数器,当计数器减为0时,等待的线程将被唤醒。计数器只能减少,不能增加。
示例:使用CountDownLatch等待所有线程完成任务
假设我们有一个任务需要三个子任务完成,我们可以使用CountDownLatch来等待所有子任务完成。
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 1; i <= 3; i++) {
final int taskNumber = i;
new Thread(() -> {
System.out.println("Task " + taskNumber + " started");
try {
Thread.sleep(1000 * taskNumber);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task " + taskNumber + " completed");
latch.countDown();
}).start();
}
System.out.println("Waiting for all tasks to complete...");
latch.await();
System.out.println("All tasks completed");
}
}
复制代码
在这个示例中,我们创建了一个CountDownLatch并设置初始计数器为3。每个子任务完成后,调用latch.countDown()减少计数器。主线程调用latch.await()等待所有子任务完成。
5.5.2 CyclicBarrier
CyclicBarrier是一个同步辅助类,它允许一组线程相互等待,直到所有线程都准备好继续执行。当所有线程都到达屏障点时,屏障将打开。CyclicBarrier可以重复使用。
示例:使用CyclicBarrier同步多个线程
假设我们有三个线程需要在某个点同步,我们可以使用CyclicBarrier实现这个目的。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All threads are ready to proceed"));
for (int i = 1; i <= 3; i++) {
final int taskNumber = i;
new Thread(() -> {
System.out.println("Task " + taskNumber + " is ready");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("Task " + taskNumber + " is proceeding");
}).start();
}
}
}
复制代码
在这个示例中,我们创建了一个CyclicBarrier并设置参与者数量为3。每个线程在准备好继续执行之前调用barrier.await()。当所有线程都准备好时,屏障将打开,所有线程将继续执行。
5.5.3 Semaphore
Semaphore是一个计数信号量,它维护了一个许可集。线程可以请求许可,如果有可用的许可,线程将获得许可并继续执行。否则,线程将阻塞,直到有可用的许可。许可可以由任何线程释放。Semaphore可用于实现资源池、限制并发访问等。
示例:使用Semaphore限制并发访问
假设我们有一个只能同时处理三个请求的服务器,我们可以使用Semaphore来实现并发访问限制。
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 10; i++) final int clientNumber = i;
new Thread(() -> {
try {
System.out.println("Client " + clientNumber + " is trying to connect");
semaphore.acquire();
System.out.println("Client " + clientNumber + " is connected");
Thread.sleep(2000);
System.out.println("Client " + clientNumber + " is disconnected");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}).start();
}
}
}
复制代码
在这个示例中,我们创建了一个Semaphore并设置初始许可数量为3。每个客户端线程在连接服务器之前调用semaphore.acquire()请求许可。当许可可用时,线程将获得许可并继续执行。线程完成后,调用semaphore.release()释放许可。
5.5.4 Exchanger
Exchanger是一个同步辅助类,它允许两个线程在一个临界点交换数据。当两个线程都到达交换点时,它们将交换数据。Exchanger可以用于遗传算法、管道设计等。
示例:使用Exchanger交换数据
假设我们有两个线程,一个生成数据,另一个处理数据。我们可以使用Exchanger在这两个线程之间交换数据。
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
try {
String data = "Data from producer";
System.out.println("Producer is sending: " + data);
String receivedData = exchanger.exchange(data);
System.out.println("Producer received: " + receivedData);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String data = "Data from consumer";
System.out.println("Consumer is sending: " + data);
String receivedData = exchanger.exchange(data);
System.out.println("Consumer received: " + receivedData);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
复制代码
在这个示例中,我们创建了一个Exchanger。生产者和消费者线程在交换数据前调用exchanger.exchange(data)。当两个线程都到达交换点时,它们将交换数据。
5.5.5 Phaser
Phaser是一个灵活的同步辅助类,它允许一组线程相互等待,直到所有线程都准备好继续执行。与CyclicBarrier类似,但Phaser更加灵活,可以动态调整参与者数量和支持多个阶段。
示例:使用Phaser同步多个线程
假设我们有三个线程需要在某个点同步,我们可以使用Phaser实现这个目的。
import java.util.concurrent.Phaser;
public class PhaserExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(3);
for (int i = 1; i <= 3; i++) {
final int taskNumber = i;
new Thread(() -> {
System.out.println("Task " + taskNumber + " is ready");
phaser.arriveAndAwaitAdvance();
System.out.println("Task " + taskNumber + " is proceeding");
}).start();
}
}
}
复制代码
在这个示例中,我们创建了一个Phaser并设置参与者数量为3。每个线程在准备好继续执行之前调用phaser.arriveAndAwaitAdvance()。当所有线程都准备好时,屏障将打开,所有线程将继续执行。
这些并发工具类为Java多线程编程提供了强大的支持,帮助我们更轻松地实现各种同步和并发场景。希望这些示例能帮助你理解并掌握这些工具类的用法。
推荐阅读:
https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA
https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
正序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
发新帖
回复
守听
金牌会员
这个人很懒什么都没写!
楼主热帖
【网络编程】从零开始搭建一个开源博客 ...
Vulnhub靶机-Al-Web-1
【CSDN云VS腾讯云】要不然怎么说CSDN开 ...
面试官:BIO、NIO、AIO是什么,他们有 ...
报错building for iOS Simulator, but ...
Python学习:import的正确用法
TCP协议
如何成为一名开发人员——第 3 部分: ...
全网最新的nacos 2.1.0集群多节点部署 ...
UWP/WinUI3 Win2D PixelShaderEffec ...
标签云
挺好的
服务器
快速回复
返回顶部
返回列表