J*a里如何实现线程安全的事件发布与订阅_事件发布订阅线程安全操作说明


使用CopyOnWriteArrayList可实现线程安全的事件发布订阅,适合读多写少场景;通过读写锁+列表快照可提升高并发性能,结合线程池支持异步分发,确保事件处理不阻塞发布线程,根据场景选择方案。

java里如何实现线程安全的事件发布与订阅_事件发布订阅线程安全操作说明

在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保护监听器集合。

示例:使用读写锁提升性能

Claude Claude

Anthropic发布的与ChatGPT竞争的聊天机器人

Claude 1166 查看详情 Claude
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 (EventListener listener : safeListeners) {
        executor.submit(() -> listener.onEvent(event));
    }
}

注意:异步模式下事件顺序不保证,需根据业务决定是否使用单线程线程池(如newSingleThreadExecutor)来保序。

基本上就这些。选择哪种方式取决于你的使用场景:轻量级用CopyOnWriteArrayList,功能复杂可配合读写锁和线程池,关键是保证监听器列表的线程安全和事件发布的稳定性。

以上就是J*a里如何实现线程安全的事件发布与订阅_事件发布订阅线程安全操作说明的详细内容,更多请关注其它相关文章!


# 适用于  # 论坛怎么做seo排名  # 广东景物网站建设  # seo黑帽招聘技巧  # 西安网站推广威心hfqjwl做词  # 宁波集团公司网站建设  # 网站中关键词优化  # 企业网站优化哪家便宜  # 武清区营销推广方法  # 巩义网站优化哪家售后好  # 营销推广4p4c  # 相关文章  # java  # 遍历  # 多个  # 多写  # 过程中  # 配置文件  # 回调  # 如何实现  # 数据结构  # 有锁  # 线程安全 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: J*aScript 数值去小数位处理:多种方法与实践  Win11如何分屏操作_Win11多窗口分屏技巧  阿里旺旺电脑网页版入口 阿里旺旺电脑版网页登录入口  Cassandra中复合主键、二级索引与ORDER BY排序的限制与解决方案  猫眼电影app如何参与官方的抽奖活动_猫眼电影官方抽奖参与方法  房产|直播|视频号怎么认证开通?|直播|需要什么资质?  家里的小飞虫总是不断,用什么方法可以彻底根除?  Golang如何操作指针参数_Go pointer参数传递规则  163邮箱在线登录 163邮箱网页版在线入口  Win10如何关闭操作中心通知 Win10免打扰设置全攻略【清爽】  C++如何使用CMake构建项目_C++ CMakeLists.txt编写入门教程  163邮箱网页版官方登录入口 163邮箱网页版访问页面  如何外贸网站设计-能留住客户提升用户体验!  鸿蒙单条备忘录如何加密  Golang如何使用gRPC拦截器实现日志收集_Golang gRPC拦截器日志收集实践  火狐浏览器无法自动更新怎么办 手动更新火狐浏览器到最新版本【解决】  如何在CSS中设置背景图像:一个全面指南  search中maxlength属性用法解析  网页版网易云音乐入口_网易云音乐在线官网登录  纯CSS实现自适应宽度与响应式布局的水平按钮组  vivo云服务一直提示空间不足怎么办 怎么办vivo云服务老是提示空间不足  Python中对象引用与链表属性赋值的机制解析  如何使用CSS Grid实现“大方块左侧,小方块右侧垂直堆叠”的水平布局  sf漫画官网登录入口直达_sf漫画官方正版网址  《鹿路通》退余额方法  抖音小程序怎么开通?小程序开通条件是什么?  Python自动化抓取GBGB赛狗比赛结果:日期范围与赛道筛选教程  TikTok网页版入口快速访问 TikTok官网账号登录方法  CSS如何控制元素外边距_margin实现布局间隔  为什么XML解析器对大小写敏感? 理解XML规范中的大小写规则与最佳实践  怎样让Windows 11的开始菜单恢复经典样式_Open-Shell工具使用指南【怀旧】  Sublime怎么配置YAML文件格式化_Sublime YAML Formatter插件教程  手机远程连接电脑方法  济南公交卡手机充值指南  喜茶GO更换登录账号方法  告别阻塞等待:如何使用GuzzlePromises优雅处理PHP异步操作,提升应用响应速度  c++如何实现观察者设计模式_c++行为型设计模式实战  铁路12306官网入口 铁路12306中国铁路官网登录首页  Flexbox布局中Stencil组件宽度不显示问题解析与:host尺寸控制  KFC邀请码怎么使用领额外优惠_KFC邀请码输入方式与额外优惠代码获取方法  《海贝音乐》均衡器设置方法  苹果11如何更换iCloud账号_苹果11账号切换的具体步骤  263企业邮箱如何设置邮件转发功能  六级准考证号怎么查_四六级准考证查询入口官网  Highcharts雷达图轴线交点数值标注指南  iPhone12是否要更新ios16  mysql离线安装后如何启动_mysql离线安装完成后启动服务的方法  Sublime怎么格式化HTML代码_Sublime前端代码美化插件使用指南  智学网app怎么登录忘记密码_智学网app忘记密码找回与重新登录操作方法  BunnyStream TUS视频上传指南:解决401认证错误与参数配置 

 2025-12-05

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.