线程模型

在EventBus3.0框架中执行线程的快速切换,通过ThreadMode来指定线程在哪个线程中执行;

在EventBus3.0框架线程模型有个PendingPost 类负责数据的传递;

final class PendingPost {
private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();
Object event;
Subscription subscription;
PendingPost next; private PendingPost(Object event, Subscription subscription) {
this.event = event;
this.subscription = subscription;
}
}

PendingPost 类中维护了3个字段,其中event为事件类的实例,subscription是监听回调信息封装,next 的类型也是一个PendingPost ,通过next可以构建一个列表;

在类的内部也维护着一个静态的PendingPost 对象的对象池,当需要PendingPost 实例时,首先从对象池中获取,当获取不到时在进行对象的new创建;

ThreadMode.MAIN 当调用线程不是主线程时,需要把事件执行推送到主线程中,在EventBus3.0框架中的EventBus类中维护着一个HandlerPoster对象来进行主线程数据的处理;HandlerPoster类是一个Handler,监听事件函数的执行应该在主线程回调的handleMessage 方法中,在源码中也确实是在handleMessage方法执行:

    eventBus.invokeSubscriber(pendingPost);

   ThreadMode.Background 与ThreadMode.AsyncPoster 执行的方式差不多相同,都是从后台线程池中取出线程进行执行;在EventBus类中初始化了BackgroundPoster与AsyncPoster来对这2种线程模型进行处理,这2个类都继承了Runnable 接口;
final class BackgroundPoster implements Runnable {

    private final PendingPostQueue queue;
private final EventBus eventBus; private volatile boolean executorRunning; BackgroundPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
} public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
eventBus.getExecutorService().execute(this);
}
}
}
}

在BackgroundPoster 类中PendingPostQueue 是一个存储了PendingPost类型的队列,eventBus对应的就是EventBus类的实例,在BackgroundPoster 类中enqueue方法是在EventBus分发Post方法内部进行调用的;

 eventBus.getExecutorService()获取EventBus类中的ExecutorService,在源码我们可以发现ExecutorService=Executors.newCachedThreadPool();
 当执行eventBus.getExecutorService().execute(this);代码时,就跳转到BackgroundPoster 的run方法中
 @Override
public void run() {
try {
try {
while (true) {
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
executorRunning = false;
return;
}
}
}
eventBus.invokeSubscriber(pendingPost);
}
} catch (InterruptedException e) {
Log.w("Event", Thread.currentThread().getName() + " was interruppted", e);
}
} finally {
executorRunning = false;
}
}

从run方法中可以看出,最终执行的还是eventBus.invokeSubscriber(pendingPost) 方法;

由浅入深了解EventBus:(六)的更多相关文章

  1. 由浅入深了解EventBus:(五)

    事件分发 EventBus3.0的事件的分发时通过EventBus类中的post(粘性事件为postSticky)方法,post与postSticky的唯一区别就是,在postSticky内部首先会向 ...

  2. 由浅入深了解EventBus:(四)

    事件注册 在EventBus3.0框架中订阅者对事件进行注册/订阅是通过EventBus类中的register方法来实现的,register的方法参数就是我们的订阅者的实例; public void ...

  3. 由浅入深了解EventBus:(三)

    原理 EventBus的核心工作机制如下图 在EventBus3.0架构图: EventBus类 在EventBus3.0框架的内部,核心类就是EventBus,订阅者的注册/订阅,解除注册,以及事件 ...

  4. 由浅入深了解EventBus:(二)

    概念 深入学习EventBus框架,就必须理解EventBus的相关原理和一些概念: Subscribe 在EventBus框架中,消息的处理接收方法必须要“@Subscribe”注解来进行标注: p ...

  5. 由浅入深了解EventBus:(一)

    概述 由greenrobot织贡献(该组织还贡献了greenDAO),一个Android事件发布/订阅轻量级框架; EventBus是一个消息总线,以观察者模式实现,用于简化程序的组件.线程通信,可以 ...

  6. C#总结(六)EventBus事件总线的使用-自己实现事件总线

    在C#中,我们可以在一个类中定义自己的事件,而其他的类可以订阅该事件,当某些事情发生时,可以通知到该类.这对于桌面应用或者独立的windows服务来说是非常有用的.但对于一个web应用来说是有点问题的 ...

  7. 即时聊天APP(六) - 消息的接收以及EventBus使用

    通常我们在接收消息的时候会有声音和震动的提示,因此我也加了代码达到这样的效果,这就要用到EventBus了,当然这里我也用到了自定义的广播,所以首先在Mainfests文件中加入以下代码: <r ...

  8. Elasticsearch由浅入深(六)批量操作:mget批量查询、bulk批量增删改、路由原理、增删改内部原理、document查询内部原理、bulk api的奇特json格式

    mget批量查询 批量查询的好处就是一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的如果进行批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的 ...

  9. Spring源码由浅入深系列六 CreateBean过程

随机推荐

  1. POJ - 2175 Evacuation Plan (最小费用流消圈)

    题意:有N栋楼,每栋楼有\(val_i\)个人要避难,现在有M个避难所,每个避难所的容量为\(cap_i\),每个人从楼i到避难所j的话费是两者的曼哈顿距离.现在给出解决方案,问这个解决方案是否是花费 ...

  2. quic协议实践

    QUIC实践 环境Ubuntu14.x86_64 gcc4.8 python2.7 编译QUIC服务器和客户端 下载 git clone https://github.com/google/proto ...

  3. redis数据持久化内存不足

    原因:写数据到redis里面写不进去,查看redis日志显示: Can't save in background: fork: Cannot allocate memory 在小内存的进程上做一个fo ...

  4. Ubuntu 16.04 安装Postman

    Ubuntu 16.04 安装Postman: 1.官网下载地址:https://www.getpostman.com/根据机器类型选择64位下载. 2.进入下载目录,解压该文件sudo tar -x ...

  5. ABP官方文档翻译 1.3 模块系统

    ABP模块系统 介绍 模块定义 生命周期方法 PreInitialize Initialize PostInitialize Shutdown 模块依赖 插件系统 ASP.NET Core ASP.N ...

  6. std::tuple作为参数invoke调用函数

    template<typename Function, typename Tuple, std::size_t... Index> decltype(auto) invoke_impl(F ...

  7. SVN 命令符号详解

    L abc.c # svn已经在.svn目录锁定了abc.c M bar.c # bar.c的内容已经在本地修改过了 M baz.c # baz.c属性有修改,但没有内容修改 X 3rd_party ...

  8. SublimeText2 编辑器使用小结

    用SublimeText 2进行前端开发也有一段时间了,所谓“工欲善其事必先利其器”,前几日对照着网易课程又重新温习总结了一下有关SublimeText编辑器的使用方式,有所收获,在此进行一次小小的总 ...

  9. Ansible Playbooks 常用模块

    官网链接:https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html ansible python module ...

  10. Nodejs Q promise设计思路

    Nodejs Q promise库 前言 Q库为nodejs提供了一个基于promise的编程方式,从此避免了一层又一层的callback调用.不过Q的灵活性也给我造成了很大困扰,我可以用promis ...