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);
}
}
相關文章
- EventBus原始碼解讀詳細註釋(2)MainThread執行緒模型分析原始碼AIthread執行緒模型
- EventBus四種執行緒交付模式執行緒模式
- EventBus原始碼解讀詳細註釋(1)register的幕後黑手原始碼
- EventBus原始碼解讀詳細註釋(4)register時重新整理的兩個map原始碼
- EventBus原始碼解讀詳細註釋(5)事件訊息繼承性分析 eventInheritance含義原始碼事件繼承
- EventBus原始碼解讀詳細註釋(6)從事件釋出到事件處理,究竟發生了什麼!原始碼事件
- java多執行緒之interrupted()和isInterrupted()的區別(原始碼解讀)Java執行緒原始碼
- EventBus原始碼分析(四):執行緒模型分析(2.4版本)原始碼執行緒模型
- java中常見的四種執行緒池的區別Java執行緒
- Bootstrap的Model原始碼詳細註釋 (轉)boot原始碼
- 執行Shell指令碼的4種方法及區別詳解指令碼
- 詳細解讀微服務的兩種模式微服務模式
- EventBus 3.0+ 原始碼詳解(史上最詳細圖文講解)原始碼
- 多執行緒-多執行緒兩種方式的圖解比較及區別執行緒圖解
- EventBus詳解及原始碼分析原始碼
- 詳解Java執行緒池的ctl(執行緒池控制狀態)【原始碼分析】Java執行緒原始碼
- singleton模式四種執行緒安全的實現模式執行緒
- 【乾貨】趣味詳解 3 種 Python 執行緒鎖Python執行緒
- POSIX 執行緒詳解(3) (轉)執行緒
- 執行緒封閉之ThreadLocal原始碼詳解執行緒thread原始碼
- Android 註解系列之 EventBus3 原理(四)AndroidS3
- java執行緒中yield(),sleep(),wait()區別詳解Java執行緒AI
- 深入併發之(四) 執行緒池詳細分析執行緒
- 詳細解讀:遠端執行緒注入DLL到PC版微信執行緒
- JAVA多執行緒詳解(3)執行緒同步和鎖Java執行緒
- 執行緒建立的四種方式執行緒
- 註解和註釋區別
- Java執行緒池從使用到閱讀原始碼(3/10)Java執行緒原始碼
- java的執行緒、建立執行緒的 3 種方式、靜態代理模式、Lambda表示式簡化執行緒Java執行緒模式
- Netty原始碼分析之Reactor執行緒模型詳解Netty原始碼React執行緒模型
- 程式、執行緒詳細梳理執行緒
- Android執行緒篇(一)實現執行緒的幾種方法及區別Android執行緒
- java--執行緒池--建立執行緒池的幾種方式與執行緒池操作詳解Java執行緒
- 執行緒池以及四種常見執行緒池執行緒
- MySQL explain執行計劃詳細解釋MySqlAI
- JDK提供的四種執行緒池JDK執行緒
- 常見的四種執行緒池執行緒
- java 四種執行緒池的使用Java執行緒