EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别
来源:互联网 发布:签收后淘宝介入 编辑:程序博客网 时间:2024/06/06 03:43
[EventBus源码分析(一):入口函数提纲挈领(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51802172)
[EventBus源码分析(二):register方法保存事件的订阅者列表(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51819508)
[EventBus源码分析(三):post方法发布事件【获取事件的所有订阅者,反射调用订阅者事件处理方法】(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51821143)
[EventBus源码分析(四):线程模型分析(2.4版本)](http://blog.csdn.net/wangshihui512/article/details/51832001)
[EventBus源码解读详细注释(1)register的幕后黑手](http://blog.csdn.net/wangshihui512/article/details/50914817)
[EventBus源码解读详细注释(2)MainThread线程模型分析](http://blog.csdn.net/wangshihui512/article/details/50934012)
[EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别](http://blog.csdn.net/wangshihui512/article/details/50935729)
[EventBus源码解读详细注释(4)register时刷新的两个map](http://blog.csdn.net/wangshihui512/article/details/50938663)
[EventBus源码解读详细注释(5)事件消息继承性分析 eventInheritance含义](http://blog.csdn.net/wangshihui512/article/details/50947102)
[EventBus源码解读详细注释(6)从事件发布到事件处理,究竟发生了什么!](http://blog.csdn.net/wangshihui512/article/details/50949960)
PostThread:直接在发布者线程调用事件处理方法
MainThread:如果发布者线程是主线程,那么直接在发布者线程(主线程)里边调用事件处理方法;如果发布者线程不是主线程,就把此事件送到主线程消息循环处理队列,在主线程中处理此事件
BackgroundThread:如果发布者线程是主线程,那么把此事件发送到一个专门处理后台线程的消息循环处理队列,该队列管理多个后台线程;如果发布者不是主线程,那么在发布者线程中直接调用事件处理方法
Async:并不使用队列管理多个事件,也不管发布者处在主线程与否,为每一个事件单独开辟一个线程处理
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) { case PostThread: /*在发布者的线程里边通过反射执行事件处理方法*/ invokeSubscriber(subscription, event); break; case MainThread: /*如果发布者线程是主线程,直接在主线程里边通过反射执行事件处理方法*/ if (isMainThread) { invokeSubscriber(subscription, event); /*如果发布者线程不是主线程,就把此事件加入主线程消息循环处理队列,在主线程中 * 通过反射调用事件处理方法*/ } else { mainThreadPoster.enqueue(subscription, event); } break; case BackgroundThread: /*如果发布者线程是主线程,那么就把此事件加入后台线程消息循环处理队列 * 通过反射调用事件处理方法,此线程模式多个事件都在一个后台线程中循环处理 * 通过队列管理多个事件*/ if (isMainThread) { backgroundPoster.enqueue(subscription, event); } else { /*发布者不在主线程,那么在发布者线程中直接通过反射调用事件处理方法*/ invokeSubscriber(subscription, event); } break; case Async: /*这种线程模式是直接开一个新的线程,调用事件处理方法,虽然看起来像是 * 通过队列在一个后台线程中循环管理多个事件,但是通过阅读源码发现并不是这样, * 而是为每一个事件都单独开辟一个线程*/ asyncPoster.enqueue(subscription, event); break; default: throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode); } }
MianThread线程模型参看上篇 Event源码解读详细注释(2)MainThread线程模型分析
BackgroundThread线程模型通过队列管理多个线程
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; /*进队列后判断此线程是否在执行,如果没有在执行就执行此线程(调用run方法)*/ eventBus.getExecutorService().execute(this); } } } /*线程执行体*/ @Override public void run() { try { try { /*循环处理消息*/ while (true) { /*消息队列队首出队列,将被挂起1秒,直到有消息入队列或者1秒到时*/ PendingPost pendingPost = queue.poll(1000); /*队列为空*/ 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; } }}
Async线程模型为每一个事件单独开辟一个线程:
class AsyncPoster implements Runnable { private final PendingPostQueue queue; private final EventBus eventBus; AsyncPoster(EventBus eventBus) { this.eventBus = eventBus; queue = new PendingPostQueue(); } public void enqueue(Subscription subscription, Object event) { PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event); queue.enqueue(pendingPost); /*进队列后就立即执行此线程,为每一个事件单独开一个线程,因此不需要判断线程是否在执行,也不需要循环遍历*/ eventBus.getExecutorService().execute(this); } @Override public void run() { /*为每一个事件单独开一个线程,因此不需要判断线程是否在执行,也不需要循环遍历*/ PendingPost pendingPost = queue.poll(); if(pendingPost == null) { throw new IllegalStateException("No pending post available"); } /*线程执行体里边直接通过反射调用事件处理方法*/ eventBus.invokeSubscriber(pendingPost); }}
0 0
- EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别
- EventBus源码解读详细注释(2)MainThread线程模型分析
- EventBus源码解读详细注释(1)register的幕后黑手
- EventBus源码解读详细注释(4)register时刷新的两个map
- EventBus源码解读详细注释(5)事件消息继承性分析 eventInheritance含义
- EventBus源码解读详细注释(6)从事件发布到事件处理,究竟发生了什么!
- EventBus四种线程交付模式
- EventBus四种线程交付模式
- android-async-http源码解读(一)
- android-async-http源码解读(二)
- 超详细的java线程池源码解读
- 解读EventBus源码
- EventBus源码注释分析
- UDT源码剖析(四):UDT的GC线程相关过程代码注释
- UDT源码剖析(四):UDT的GC线程相关过程代码注释
- defer和async的详细区别
- defer和async的详细区别
- Netty源码解读(四)Netty与Reactor模式
- java内部类的使用
- 学习日志
- Axis、Axis2和CXF比较
- iOS - 屏幕旋转
- volatile 理解
- EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别
- 一些我推荐的和想上的网络课程(Coursera, edX, Udacity,MIT OCW)
- leetcode 23. Merge k Sorted Lists
- FragmentTabhost的使用
- HYSBZ 1151 动物园zoo - 状压dp
- YJUtilsDirectory
- ListView的局部刷新
- 关于圆锥的体积公式
- Python 随机数生成的几种方法