新闻中心
J*a里如何实现线程安全的事件发布与订阅_事件发布订阅线程安全操作说明
使用CopyOnWriteArrayList可实现线程安全的事件发布订阅,适合读多写少场景;通过读写锁+列表快照可提升高并发性能,结合线程池支持异步分发,确保事件处理不阻塞发布线程,根据场景选择方案。

在J*a中实现线程安全的事件发布与订阅,关键在于确保多个线程同时注册、注销或触发事件时不会引发并发问题。常见的做法是使用线程安全的数据结构来管理监听器列表,并保证事件发布过程中的读写一致性。
使用CopyOnWriteArrayList管理监听器
最简单且高效的线程安全方式是使用CopyOnWriteArrayList存储订阅者(监听器)。该集合在修改时会复制底层数组,适合读多写少的场景,如事件广播。
示例代码:
import j*a.util.concurrent.CopyOnWriteArrayList;
public class EventBus {
private final CopyOnWriteArrayList<EventListener> listeners = new CopyOnWriteArrayList<>();
public void subscribe(EventListener listener) {
listeners.add(listener);
}
public void unsubscribe(EventListener listener) {
listeners.remove(listener);
}
public void publish(Event event) {
for (EventListener listener : listeners) {
listener.onEvent(event);
}
}
}
interface EventListener {
void onEvent(Event event);
}
class Event {
private final String data;
public Event(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
说明:CopyOnWriteArrayList在遍历过程中允许添加/删除操作,不会抛出ConcurrentModificationException,非常适合事件通知这种频繁读取、较少变更的场景。
使用显式同步控制(适用于复杂逻辑)
如果需要更细粒度的控制,比如支持按类型订阅、异步分发等,可以使用synchronized或ReentrantReadWriteLock保护监听器集合。
示例:使用读写锁提升性能
Writer
企业级AI内容创作工具
220
查看详情
import j*a.util.ArrayList;
import j*a.util.List;
import j*a.util.concurrent.locks.ReadWriteLock;
import j*a.util.concurrent.locks.ReentrantReadWriteLock;
public class ThreadSafeEventBus {
private final List<EventListener> listeners = new ArrayList<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void subscribe(EventListener listener) {
lock.writeLock().lock();
try {
listeners.add(listener);
} finally {
lock.writeLock().unlock();
}
}
public void unsubscribe(EventListener listener) {
lock.writeLock().lock();
try {
listeners.remove(listener);
} finally {
lock.writeLock().unlock();
}
}
public void publish(Event event) {
lock.readLock().lock();
try {
// 创建快照避免持有锁期间调用回调
List<EventListener> safeListeners = new ArrayList<>(listeners);
for (EventListener listener : safeListeners) {
listener.onEvent(event);
}
} finally {
lock.readLock().unlock();
}
}
}
优势:读操作不阻塞,适合高频率事件发布;通过拷贝监听器列表,避免在锁内执行可能耗时的回调方法。
异步事件分发与线程池集成
若事件处理较耗时,建议将事件分发交给线程池,避免阻塞发布线程。
改进publish方法:
private final ExecutorService executor = Executors.newFixedThreadPool(4);
public void publish(Event event) {
lock.readLock().lock();
List<EventListener> safeListeners;
try {
safeListeners = new ArrayList<>(listeners);
} finally {
lock.readLock().unlock();
}
for (Eve
ntListener listener : safeListeners) {
executor.submit(() -> listener.onEvent(event));
}
}
注意:异步模式下事件顺序不保证,需根据业务决定是否使用单线程线程池(如newSingleThreadExecutor)来保序。
基本上就这些。选择哪种方式取决于你的使用场景:轻量级用CopyOnWriteArrayList,功能复杂可配合读写锁和线程池,关键是保证监听器列表的线程安全和事件发布的稳定性。以上就是J*a里如何实现线程安全的事件发布与订阅_事件发布订阅线程安全操作说明的详细内容,更多请关注其它相关文章!
# 遍历
# seo定制培训
# 潢川企业号推广营销费用
# 晴隆抖音seo咨询
# 网站建设优化案例
# 无锡网站建设网站运营
# 湘潭网站建设管理论文
# 河北网站建设官网
# 大余关键词优化排名
# 合肥网站建设公司哪家好
# 成都seo排名费用
# 适用于
# java
# 多个
# 多写
# 过程中
# 时长
# 回调
# 如何实现
# 好了
# 数据结构
# 有锁
# 线程安全
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
抓大鹅无需下载版 抓大鹅秒玩版入口
CSS Flexbox与媒体查询:实现响应式布局中元素的并排与堆叠
C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程
Spring Boot嵌入式服务器与J*a EE:功能支持深度解析
Python自定义类排序:解决lambda键值访问TypeError的实践指南
windows10怎么关闭系统提示音_windows10彻底静音设置方法
Surface怎么安装系统 微软Surface Pro U盘重装win11教程
微博网页版首页入口 微博电脑端官网登录链接
SteamMachine定价或为699美元 大家想入手吗?
将HTML Canvas内容转换为可上传的图像文件(File对象)
J*a TimerTask中HashMap意外清空的深层原因与解决方案
Flexbox布局实践:实现粘性导航栏与底部固定页脚
J*aScript:在map操作中高效处理空数组
Python vgamepad库按键模拟:正确使用XUSB_BUTTON常量
Windows7怎么硬盘安装 Windows7提取ISO镜像到非系统盘并运行setup.exe实现硬盘直装【教程】
HTML长属性值处理:表单action路径优化与代码规范应对
中兴Axon42Ultra怎样在文件App筛图_iPhone中兴Axon42Ultra文件App筛图【图片筛选】
凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法
mysql备份恢复性能优化_mysql备份恢复性能优化方法
在J*a中如何隐藏复杂性_使用门面模式组织对象交互
TikTok评论显示延迟如何处理 TikTok评论刷新优化方法
离线运行Go语言之旅:本地部署与GOPATH配置指南
拷贝漫画电脑版官网入口 拷贝漫画(PC版)在线直达
Node.js CSV 数据处理:基于字段值条件过滤整条记录的策略
在J*a中如何使用Stream.map转换元素_Stream映射操作解析
腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录
俄罗斯搜索引擎Yandex指南 附2025年免登录官网入口
win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】
淘宝支付提示失败如何解决 淘宝支付流程优化方法
Promise错误处理:在catch后终止链式then执行的策略
基于动态规划的房屋花卉种植最小成本算法详解
win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法
c++中的std::basic_string的SSO优化_c++短字符串优化深度解析
深入理解Promise链:如何在catch后中断then的执行
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
京东单号查询入口_京东快递订单追踪入口
邮政快递单号查询入口 邮政快递物流信息在线查询入口
J*a应用程序首次运行自动创建文件与目录的最佳实践
随机参数递归函数的基准调用次数与时间复杂度探究
Spyder启动失败:字体文件权限拒绝错误解决方案
如何在CSS中使用visited与link控制链接颜色_visited link伪类配合
在FastAPI中利用lifespan与依赖注入高效管理Redis连接池
windows10怎么查看本机ip_windows10命令提示符ipconfig使用
C++如何使用AddressSanitizer(ASan)_C++调试工具中检测内存访问错误的利器
Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】
怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】
12306几点到几点不能订票? | 官方最新系统维护时间全解析
Python Socket多播通信中指定源IP地址的实践指南
《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!
海棠电脑版入口_通过电脑访问海棠官网阅读


2025-12-05
浏览次数:次
返回列表
ntListener listener : safeListeners) {
executor.submit(() -> listener.onEvent(event));
}
}