EventBus四種執行緒交付模式
EventBus四種執行緒交付模式
原創 2016年11月05日 10:58:02
1、四種模式分別是:POSTING、MAIN、BACKGROUND、ASYNC。如果是想更新UI就使用MAIN模式,如果要進行耗時操作最好是使用ASYNC,因為這個模式能永遠保證在不一樣的執行緒中進行操作,而且都是子執行緒。
(1)POSTING:這種模式就是eventBus預設的模式,我們在使用的時候不需要再訂閱者的方法的註解後面加任何東西(選擇模式),但是這種只能在同一個執行緒中接收,也就是說,如果是在主執行緒中釋出訊息就只能在主執行緒中接收訊息,如果是在子執行緒中,那麼也只能在相同的子執行緒中去接收訊息。如果非要宣告POSTING的話,寫法如下:
@Subscribe(threadMode = ThreadMode.POSTING)
public void
showMsgFromSecondActivity(MessagePojo
msg){ Log.i("test",
((String) msg.obj));
}
(2)MAIN:這種模式保證了訂閱者指定的那個接收方法肯定要主執行緒中執行,可以放心的在裡面執行更新UI操作。無論釋出者是在主執行緒中還是在那一條子執行緒中釋出訊息,這邊接收的都在主執行緒中。寫法如下
@Subscribe(threadMode = ThreadMode.MAIN)
public void
showMsgFromSecondActivity(MessagePojo
msg){ Log.i("test",
((String) msg.obj));
}
(3)BACKGROUND:這種模式無論釋出者是在主執行緒或者是那一條子執行緒中釋出訊息,接收的肯定是在子執行緒中,並且是這樣理解:如果是在主執行緒中釋出訊息,那麼就會隨機開闢一條子執行緒來接收訊息。如果是在子執行緒中釋出訊息,那麼就會在相同的子執行緒來接收訊息。寫法如下:
@Subscribe(threadMode = ThreadMode.BACKGROUDN)
public void
showMsgFromSecondActivity(MessagePojo
msg){ Log.i("test",
((String) msg.obj));
}
(4)ASYNC:這種模式是無論你在那個執行緒中釋出訊息都會在不同的執行緒中接受訊息。如果你在主執行緒中釋出訊息,就會隨機的開闢一條子執行緒來接收訊息;如果是在子執行緒中釋出訊息,就會開闢一條不同的子執行緒來接收訊息。
寫法如下:
@Subscribe(threadMode = ThreadMode.ASYNC)
public void
showMsgFromSecondActivity(MessagePojo
msg){ Log.i("test",
((String) msg.obj));
}
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);
- }
-
}
相關文章
- singleton模式四種執行緒安全的實現模式執行緒
- 執行緒池以及四種常見執行緒池執行緒
- 執行緒建立的四種方式執行緒
- EventBus原始碼分析(四):執行緒模型分析(2.4版本)原始碼執行緒模型
- EventBus原始碼解讀詳細註釋(3)PostThread、MainThread、BackgroundThread、Async四種執行緒模式的區別原始碼threadAI執行緒模式
- JDK提供的四種執行緒池JDK執行緒
- 常見的四種執行緒池執行緒
- java 四種執行緒池的使用Java執行緒
- Java四種執行緒池的使用Java執行緒
- Java 執行緒池四種拒絕策略Java執行緒
- java自帶的四種執行緒池Java執行緒
- Java 四種執行緒池的用法分析Java執行緒
- Java建立多執行緒的四種方式Java執行緒
- C++ 執行緒同步的四種方式C++執行緒
- 執行緒安全使用 HashMap 的四種技巧執行緒HashMap
- iOS 多執行緒的四種技術方案iOS執行緒
- C++執行緒同步的四種方式(Windows)C++執行緒Windows
- Java通過Executors提供四種執行緒池Java執行緒
- 執行緒鎖(四)執行緒
- 多執行緒(四)執行緒
- java的執行緒、建立執行緒的 3 種方式、靜態代理模式、Lambda表示式簡化執行緒Java執行緒模式
- Java 多執行緒基礎(四)執行緒安全Java執行緒
- Java程式猿必會的四種執行緒池Java執行緒
- 知道執行緒池的四種拒絕策略嗎?執行緒
- 執行緒系列四AQS執行緒AQS
- iOS多執行緒安全-13種執行緒鎖?iOS執行緒
- 單例模式——執行緒安全的兩種實現單例模式執行緒
- iOS多執行緒全套:執行緒生命週期,多執行緒的四種解決方案,執行緒安全問題,GCD的使用,NSOperation的使用iOS執行緒GC
- Java併發(四)----執行緒執行原理Java執行緒
- java中常見的四種執行緒池的區別Java執行緒
- 執行緒、開啟執行緒的兩種方式、執行緒下的Join方法、守護執行緒執行緒
- 多執行緒Reactor模式執行緒React模式
- ros 多執行緒模式ROS執行緒模式
- EventBus,輕鬆實現跨元件跨執行緒通訊元件執行緒
- Concurrency(四:執行緒安全)執行緒
- 多執行緒系列(四):Task執行緒
- C#多執行緒學習(四) 多執行緒的自動管理(執行緒池)C#執行緒
- 【設計模式】實現執行緒安全單例模式的五種方式設計模式執行緒單例