EventBus源码解读详细注释(3)PostThread、MainThread、BackgroundThread、Async四种线程模式的区别

[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);
    }

}




你可能感兴趣的:(Android源码分析)