EventBus原始碼解讀詳細註釋(3)PostThread、MainThread、BackgroundThread、Async四種執行緒模式的區別
阿新 • • 發佈:2019-02-05
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); } }
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); } }