由淺入深瞭解EventBus:(六)

線程模型

  在EventBus3.0框架中執行線程的快速切換,經過ThreadMode來指定線程在哪一個線程中執行;框架

  在EventBus3.0框架線程模型有個PendingPost 類負責數據的傳遞;ide

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建立;this

    ThreadMode.MAIN 當調用線程不是主線程時,須要把事件執行推送到主線程中,在EventBus3.0框架中的EventBus類中維護着一個HandlerPoster對象來進行主線程數據的處理;HandlerPoster類是一個Handler,監聽事件函數的執行應該在主線程回調的handleMessage 方法中,在源碼中也確實是在handleMessage方法執行:spa

    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(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;
        }
    }

從run方法中能夠看出,最終執行的仍是eventBus.invokeSubscriber(pendingPost) 方法;code

相關文章
相關標籤/搜索