专栏首页Java架构沉思录EventBus原理深度解析

EventBus原理深度解析

一、问题描述

在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用EventBus。由于EventBus使用起来简单、便捷,因此,工作中会经常用到。深入理解该框架的原理就很有必要。

二、框架解析

2.1、组织结构

eventbus的组织结构如下:

eventbus主要有以下几部分组成:

1、eventbus、asyncEventBus:事件发送器。

2、event:事件承载单元。

3、SubscriberRegistry:订阅者注册器,将订阅者注册到event上,即将有注解Subscribe的方法和event绑定起来。

4、Dispatcher:事件分发器,将事件的订阅者调用来执行。

5、Subscriber、SynchronizedSubscriber:订阅者,并发订阅还是同步订阅。

2.2、运行原理

1、eventbus是基于注册监听的方式来运行的,因此,首先需要将eventbus,然后才会有事件及监听者。新建eventbus或者AsyncEventBus的方式如下:

或者

2、注册监听者。

底层就是将类eventListener中所有注解有Subscribe的方法与其Event对放在一个map中(一个event可以对应多个Subscribe的方法)。实现如下:

3、事件发送:执行指定事件类型的订阅者(包含了method),从订阅者中获取指定事件的订阅者,然后按照规则(同步、异步)执行指定的方法。

上述代码说明,如果事件没有监听者,就当作死亡事件来对待。

这里就说明,最后就是被订阅的方法被调用。

4、EventBus与AsyncEventBus的区别

从字面上看,AsyncEventBus是异步的EventBus,那么EventBus应该就是同步的了。EventBus的executor为MoreExecutors.directExecutor(),其实现如下:

其execute方法直接执行线程的run方法,即同步调用run方法执行。EventBus的dispatcher为PerThreadQueuedDispatcher。其dispatch方法如下:

dispatchEvent的实现如下:

因此,整个执行过程如下:

整个过程都是同步方式执行,因此,EventBus是同步的。

AsyncEventBus的dispatcher为LegacyAsyncDispatcher,executor为自己指定的线程池。运行流程如下:

虚线为线程池异步调度,因此,AsyncEventBus为异步方式。

5、AllowConcurrentEvents的作用

它所在的代码为:

即如果订阅者方法上有注解AllowConcurrentEvents,则返回Subscriber,否则,返回SynchronizedSubscriber。SynchronizedSubscriber的字面意思为同步订阅者,它的实现代码为:

即没有使用注解AllowConcurrentEvents的订阅者,在并发环境中,都是串行执行。这在高并发环境中,会严重影响性能。

三、使用案例

3.1、eventbus定义

3.2、注册与事件发送

3.3、订阅者定义

四、注意事项

1、在高并发的环境下使用AsyncEventBus时,发送事件可能会出现异常,因为它使用的线程池,当线程池的线程不够用时,会拒绝接收任务,就会执行线程池的拒绝策略,如果需要关注是否提交事件成功,就需要将线程池的拒绝策略设为抛出异常,并且try-catch来捕获异常。如下:

2、本文用到的guava版本如下:

本文分享自微信公众号 - Java架构沉思录(code-thinker)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • IaaS、PaaS、SaaS到底是什么鬼?

    IBM 的软件架构师 Albert Barron 曾经使用披萨作为比喻,解释这个问题。David Ng 进一步,让它变得更准确易懂。

    黄泽杰
  • 扫盲了!一个Java字符串中到底有多少个字符?

    我们知道, String.getBytes()如果不指定编码格式,Java会使用操作系统的编码格式得到字节数组,在我的MacOS中,默认使用UTF-8作为字符编...

    黄泽杰
  • 硬件内存模型到 Java 内存模型,这些硬核知识你知多少?

    Java 内存模型跟上一篇 JVM 内存结构很像,我经常会把他们搞混,但其实它们不是一回事,而且相差还很大的,希望你没它们搞混,特别是在面试的时候,搞混了的话就...

    黄泽杰
  • EventBus原理深度解析(Guava)

    在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用Event...

    java思维导图
  • EventBus 原理深度解析

    在工作中,经常会遇见使用异步的方式来发送事件,或者触发另外一个动作:经常用到的框架是MQ(分布式方式通知)。如果是同一个jvm里面通知的话,就可以使用Event...

    java思维导图
  • PayPal申请AR专利,消费者可从“AR版产品说明”系统中购物

    镁客网
  • ZK实现的分布式锁

    zk能保证集群上的路径同一时刻只有一个客户端来创建。因此,通过在集群上顺序创建和删除临时路径,在实现分布式锁的获取和释放。

    悠扬前奏
  • 电商快递:悬在顺丰头顶的双刃剑

    4月23日,顺丰控股发布2020年第一季度报告。报告显示,第一季度顺丰营业总收入335.41亿元,同比增长39.59%;归属于上市公司股东的净利润9.07亿元,...

    刘旷
  • Python计算机二级考试指南

    6. 了解Python计算生态在以下方面(不限于)的主要第三方库名称:网络爬虫、数据分析、数据可视化、机器学习、Web开发等。

    乐心湖
  • mongodb副本集的备份与恢复

    shirley

扫码关注云+社区

领取腾讯云代金券