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
原创粉丝点击