Rxjava深入理解之自己動手編寫Rxjava

jimmie_yang發表於2018-11-06

Demo的原始碼地址在 mini-rxjava, 有興趣的可以下載原始碼來看.

從觀察者模式說起

觀察者模式,是我們在平時使用的比較多的一種設計模式.
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己. 它的特點是 一個物件狀態改變給其他物件通知的問題,而且要考慮到易用和低耦合,保證高度的協作。

本文的重點不是在介紹 觀察者模式,因此這個話題就不展開討論.

Rxjava 是一種 函數語言程式設計,或者稱為鏈式呼叫模型,也是使用觀察者模式來實現事件的傳遞與監聽.

下面我們來看,Rxjava 和 普通觀察者的點區別.

  • 普通的觀察者模式通常是 一個主題,多個觀察者配合,基本上是屬於 一對多的情況.
  • Rxjava的觀察者模式通常是 一對一的關係.
  • 普通的觀察者模式是 主題資料改變時,通知觀察者資料的變動
  • Rxjava的觀察者模式是 在被觀察者(主題)呼叫subscribe方法後,觸發資料流動和觀察者接收事件.

基礎知識介紹到這裡,接下來我們來自己動手編寫Rxjava

編寫Rxjava

看一個常見的rxjava的使用示例,(原始資料,資料轉換,執行緒切換,資料接收處理一系列功能):

    public static void main(String[] args) throws InterruptedException {
        Observable.create((ObservableOnSubscribe<String>) emitter -> {
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onComplete();
        })
                .observeOn(Schedulers.io())
                .map(s -> Integer.parseInt(s) * 10)
                .subscribe(System.out::println);
        TimeUnit.SECONDS.sleep(1);
    }
    // 10
    // 20

接下來,我會一步一步帶領大家實現上述所有的功能.

一個簡單的觀察者模式

// Observer.java
// 觀察者
public interface Observer<T> {
    void onUpdate(T t);
}
// ObservableSource.java
// 被觀察者(主題)介面
public interface ObservableSource<T> {
    void subscribe(Observer<? super T> observer);
}
// Observable.java
// 具體的被觀察者(主題)
public class Observable<T> implements ObservableSource<T> {
    private T t;
    public Observable(T t) {
        this.t = t;
    }
    @Override
    public void subscribe(Observer<? super T> observer) {
        // 呼叫訂閱時,觸發觀察者更新
        observer.onUpdate(t);
    }
}

使用:

    public static void main(String[] args) {
        // 觀察者
        Observer<String> observer = s -> System.out.println(s);
        // 被觀察者(主題)
        Observable<String> observable = new Observable<>("hello");
        // 呼叫
        observable.subscribe(observer);
    }
    // hello

這樣,算是一個簡單的觀察模式了,但是這種方式很不靈活,資料在構造中直接傳入了.

接下來我們來改造一下 Observable.java類. 可以傳入一個介面來定義資料的傳遞規則,並且為Observable寫一個介面卡和一個事件分發器,為原始事件的產生提供支援.

  • 新增 Emitter介面,它是一個事件分發的介面;
  • 新增 ObservableOnSubscribe介面,它是建立 Observable例項的橋樑,並且有生產事件的功能,支援lambda方式呼叫;
  • 新增 ObservableCreate類,它是Observable的介面卡,能夠根據ObservableOnSubscribe介面,快速建立一個 Observable例項;並且內部類CreateEmitter實現了Emitter介面,用於事件的分發;
  • 修改 Observable類,新增工廠方法,能夠根據ObservableOnSubscribe介面,快速構建Observable例項;
// Emitter.java
// 事件分發器介面
public interface Emitter<T> {
    void onUpdate(T t);
}
// ObservableOnSubscribe.java
// Observable的事件分發介面
public interface ObservableOnSubscribe<T> {
    void subscribe(Emitter<T> emitter) throws Exception;
}
// Observable.java
public abstract class Observable<T> implements ObservableSource<T> {
    // 工廠方法,生產出一個Observable例項
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        return new ObservableCreate<>(source);
    }
    // 真正進行事件分發處理的方法
    abstract void subscribeActual(Observer<? super T> observer) throws Exception;
    @Override // 交給subscribeActual實現,需要子類實現
    public void subscribe(Observer<? super T> observer) throws Exception {
        subscribeActual(observer);
    }
}
// ObservableCreate.java
// Observable的一個介面卡,用於快速建立一個可以傳送事件的Observable
class ObservableCreate<T> extends Observable<T> {
    // 事件分發介面
    private final ObservableOnSubscribe<T> source;
    ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    @Override // 分發邏輯的具體程式碼
    void subscribeActual(Observer<? super T> observer) throws Exception {
        CreateEmitter<T> emitter = new CreateEmitter<>(observer);
        source.subscribe(emitter);
    }
    // 內部分發器
    static class CreateEmitter<T> implements Emitter<T> {
        private final Observer<? super T> observer;
        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }
        @Override // 這裡只是簡單的將observer觀察者的事件直接分發出去
        public void onUpdate(T t) {
            observer.onUpdate(t);
        }
    }
}

ObservableSource.javaObserver.java沒有修改,固沒有貼出,未貼出程式碼請檢視上一步.使用 :

    public static void main(String[] args) throws Exception {
        Observable.create(emitter -> {
                    emitter.onUpdate("hello");
                    emitter.onUpdate("world");
                })
                .subscribe(System.out::println);
    }
    // hello
    // world

哇! 你會發現,到此為止,你已經使用觀察模式實現了一個簡易的函數語言程式設計的程式碼了.
如果你完全理解了上述程式碼是怎麼產生的,那麼恭喜你,你已經理解rxjava最最核心的原理了.

新增事件結束和異常捕獲

上訴的程式碼,還不能夠捕獲異常和結束事件,這樣使用起來很不方便,接下來我們來改造實現它.
仿造rxjava,我們也將事件分為onNext,onError,onComplete三個事件.

需要修改 分發器介面和觀察者介面,以及Observable的介面卡.

  • 修改 Observer介面和Emitter介面, 改為onNext,onError,onComplete方法;
  • 修改 ObservableCreate類,新增異常處理和結束的邏輯;
// Observer.java
public interface Observer<T> {
    void onNext(T t);
    void onError(Throwable e);
    void onComplete();
}
// Emitter.java
public interface Emitter<T> {
    void onNext(T t);
    void onError(Throwable e);
    void onComplete();
}
// ObservableCreate.java
class ObservableCreate<T> extends Observable<T> {
    // 事件分發介面
    private final ObservableOnSubscribe<T> source;
    ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    @Override // 分發邏輯程式碼
    void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> emitter = new CreateEmitter<>(observer);
        try {
            source.subscribe(emitter);
        } catch (Exception e) {
            // 異常接收和處理
            emitter.onError(e);
        }
    }
    // 內部分發器
    static class CreateEmitter<T> implements Emitter<T> {
        private final Observer<? super T> observer;
        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }
        @Override
        public void onNext(T t) {
            observer.onNext(t);
        }
        @Override
        public void onError(Throwable e) {
            observer.onError(e);
        }
        @Override
        public void onComplete() {
            observer.onComplete();
        }
    }
}

修改過這是三個類後,我們就能接收異常和結束了.使用:

    public static void main(String[] args) {
        Observable.create((ObservableOnSubscribe<String>) emitter -> {
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onComplete();
        })
                .subscribe(new Observer<String>() {
                    @Override
                    public void onNext(String s) {
                        System.out.println(s);
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                        System.out.println("end...");
                    }
                });
    }
    // 1
    // 2
    // end...

嗯!? 雖然實現了接收異常和結束的功能,但是有時我們只需要onNext事件時,這樣的程式碼寫起來不夠優雅.

接下來我們編寫一個觀察者的介面卡,讓它能夠使用 lambda表示式來優雅的編寫程式碼.

  • 新增 Consumer介面,它是接收一個引數,無返回值的介面,用途是進行lambda方式進行引數傳遞;
  • 新增 Action介面,它是一個不接受引數,無返回值和的介面,用途也是進行lambda方式進行引數傳遞;
  • 新增 Functions類,它是一個輔助類,能獲取空Consumer和空Action實現;
  • 新增 LambdaObserver類,它會將lambda引數形式,轉化為Observer例項,進而實現lambda式的呼叫;
  • 修改 Observable類, 新增 void subscribe(Consumer<? super T> next, Action complete, Consumer<? super Throwable> error)系列的方法,讓subscribe方法真正支援 lambda式呼叫.
// Consumer.java
// 接受一個引數,無返回的介面
public interface Consumer<T> {
    void apply(T t) throws Exception;
}
// Action.java
// 不接受引數,無返回的介面
public interface Action {
    void apply() throws Exception;
}
// Functions.java
public class Functions {
    public static final Action EMPTY_ACTION = () -> {};
    public static <T> Consumer<T> emptyConsumer() {
        return t -> {};
    }
}
// LambdaObserver.java
public class LambdaObserver<T> implements Observer<T> {
    private final Consumer<? super T> onNext;
    private final Consumer<? super Throwable> onError;
    private final Action onComplete;
    public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {
        this.onNext = onNext;
        this.onError = onError;
        this.onComplete = onComplete;
    }
    @Override
    public void onNext(T t) {
        try {
            onNext.apply(t);
        } catch (Exception e) {
            onError(e);
        }
    }
    @Override
    public void onError(Throwable e) {
        try {
            onError.apply(e);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    @Override
    public void onComplete() {
        try {
            onComplete.apply();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
// Observable.java
public abstract class Observable<T> implements ObservableSource<T> {
    // 工廠方法,生產出一個Observable例項
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        return new ObservableCreate<>(source);
    }
    // 真正進行事件分發處理的方法
    abstract void subscribeActual(Observer<? super T> observer);
    @Override // 交給subscribeActual實現,需要子類實現
    public void subscribe(Observer<? super T> observer) {
        subscribeActual(observer);
    }
    // 接受3個lambda表示式的方法引數
    public void subscribe(Consumer<? super T> next, Consumer<? super Throwable> error, Action complete) {
        LambdaObserver<T> lambdaObserver = new LambdaObserver<>(next, error, complete);
        subscribe(lambdaObserver);
    }
    // 接受2個lambda表示式的方法引數
    public void subscribe(Consumer<? super T> next, Consumer<? super Throwable> error) {
        subscribe(next, error, Functions.EMPTY_ACTION);
    }
    // 接受1個lambda表示式的方法引數
    public void subscribe(Consumer<? super T> next) {
        subscribe(next, Functions.emptyConsumer(), Functions.EMPTY_ACTION);
    }
}

接下來是呼叫:

public static void main(String[] args) {
        Observable.create((ObservableOnSubscribe<String>) emitter -> {
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onComplete();
        }).subscribe(System.out::println);
    }
    // 1
    // 2

嘖嘖!?有點激動了,已經看起來有模有樣了,但是功能遠遠還不夠.

新增 是否消費事件的功能(中斷事件功能)

在上訴的程式碼中,我們無法主動中斷整個事件發生的過程.接下來我們就需要編寫 Disposable來實現onCompleteonError的自中斷,以及主動取消事件.

Rxjava中,Disposable是使用 列舉型別加上原子引用(AtomicReference)類來實現執行緒安全(具體可檢視DisposableHelper類).這種方式比較繁瑣,這裡就不用這種方式來演示,而使用 volatile宣告的狀態變數來做同步安全.

  • 新增 Disposable介面,提供中斷和是否中斷的方法;
  • 修改Observer介面, 新增onSubscribe方法,讓觀察者可以在事件傳遞前,獲取Disposable,進而可以在事件傳遞的任意階段中斷事件;
  • 修改ObservableCreate類,新增觀察者回撥onSubscribe,此回撥需在事件分發前才能起到作用;內部類CreateEmitter實現Disposable介面,在事件分發前先判斷是否被中斷了;使用volatile變數實現中斷判斷;
  • 修改LambdaObserver類,讓它實現Disposable介面,新增是否中斷的判斷;
  • 修改Observable類,新增onSubscribelambda呼叫;以及返回Disposable例項;
// Disposable.java
public interface Disposable {
    void dispose();
    boolean isDisposed();
}
// Observer.java
public interface Observer<T> {
    void onSubscribe(Disposable d);
    void onNext(T t);
    void onError(Throwable e);
    void onComplete();
}
// ObservableCreate.java
// Observable的一個介面卡,用於快速建立一個可以傳送事件的Observable
final class ObservableCreate<T> extends Observable<T> {
    // 事件分發介面
    private final ObservableOnSubscribe<T> source;
    ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    @Override // 分發邏輯程式碼
    void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> emitter = new CreateEmitter<>(observer);
        // 將中斷器回撥給observer
        observer.onSubscribe(emitter);
        try {
            source.subscribe(emitter);
        } catch (Exception e) {
            // 異常接收和處理
            emitter.onError(e);
        }
    }
    // 內部分發器
    static class CreateEmitter<T> implements Emitter<T>, Disposable {
        private final Observer<? super T> observer;
        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }
        @Override
        public void onNext(T t) {
            // 如果事件沒被消費,則進行操作
            if (!isDisposed())
                observer.onNext(t);
        }
        @Override
        public void onError(Throwable e) {
            if (!isDisposed()) {
                try {
                    observer.onError(e);
                } finally {
                    // 觸發消費,後續不再處理事件
                    dispose();
                }
            }
        }
        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    // 觸發消費,後續不再處理事件
                    dispose();
                }
            }
        }
        private volatile boolean isDisposed = false;
        @Override
        public void dispose() {
            isDisposed = true;
        }
        @Override
        public boolean isDisposed() {
            return isDisposed;
        }
    }
}
// LambdaObserver.java
public class LambdaObserver<T> implements Observer<T>, Disposable {
    private final Consumer<? super T> onNext;
    private final Consumer<? super Throwable> onError;
    private final Action onComplete;
    private final Consumer<? super Disposable> onSubscribe;
    public LambdaObserver(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
                          Action onComplete, Consumer<? super Disposable> onSubscribe) {
        this.onNext = onNext;
        this.onError = onError;
        this.onComplete = onComplete;
        this.onSubscribe = onSubscribe;
    }
    @Override
    public void onSubscribe(Disposable d) {
        try {
            onSubscribe.apply(d);
        } catch (Exception e) {
            onError(e);
        }
    }
    @Override
    public void onNext(T t) {
        if (!isDisposed())
            try {
                onNext.apply(t);
            } catch (Exception e) {
                onError(e);
            }
    }
    @Override
    public void onError(Throwable e) {
        if (!isDisposed())
            try {
                onError.apply(e);
            } catch (Exception e1) {
                e1.printStackTrace();
            } finally {
                dispose();
            }
    }
    @Override
    public void onComplete() {
        if (!isDisposed())
            try {
                onComplete.apply();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                dispose();
            }
    }
    private volatile boolean isDisposed = false;
    @Override
    public void dispose() {
        isDisposed = true;
    }
    @Override
    public boolean isDisposed() {
        return isDisposed;
    }
}
// Observable.java
public abstract class Observable<T> implements ObservableSource<T> {
    // 工廠方法,生產出一個Observable例項
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        return new ObservableCreate<>(source);
    }
    // 真正進行事件分發處理的方法
    abstract void subscribeActual(Observer<? super T> observer);
    @Override // 交給subscribeActual實現,需要子類實現
    public void subscribe(Observer<? super T> observer) {
        subscribeActual(observer);
    }
    // 接受4個lambda表示式的方法引數
    public Disposable subscribe(Consumer<? super T> next, Consumer<? super Throwable> error,
                                Action complete, Consumer<? super Disposable> onSubscribe) {
        LambdaObserver<T> lambdaObserver = new LambdaObserver<>(next, error, complete, onSubscribe);
        subscribe(lambdaObserver);
        return lambdaObserver;
    }
    // 接受3個lambda表示式的方法引數
    public Disposable subscribe(Consumer<? super T> next, Consumer<? super Throwable> error, Action complete) {
        return subscribe(next, error, complete, Functions.emptyConsumer());
    }
    // 接受2個lambda表示式的方法引數
    public Disposable subscribe(Consumer<? super T> next, Consumer<? super Throwable> error) {
        return subscribe(next, error, Functions.EMPTY_ACTION, Functions.emptyConsumer());
    }
    // 接受1個lambda表示式的方法引數
    public Disposable subscribe(Consumer<? super T> next) {
        return subscribe(next, Functions.emptyConsumer(), Functions.EMPTY_ACTION, Functions.emptyConsumer());
    }
}

到此,我們就能夠控制事件的中斷了.我們來看使用:

    private Disposable mDisposable = null;
    void disposableTest() {
        Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(3);
            emitter.onComplete();
        })
        .subscribe(integer -> {
            System.out.println(integer);
            // 3 事件將不再傳遞和接收
            if (integer == 2 && mDisposable != null)
                mDisposable.dispose();
            },
            Functions.emptyConsumer(), Functions.EMPTY_ACTION,
             d -> mDisposable = d);
    }
    // 1
    // 2
    
    // 這種方式只在,非同步的情況下使用,由於示例中目前還不支援非同步,因此以下程式碼起不了作用.
    void disposableTest2() {
    Disposable disposable = Observable
    .create((ObservableOnSubscribe<Integer>) emitter -> {
        emitter.onNext(1);
        emitter.onNext(2);
        emitter.onNext(3);
        emitter.onComplete();
    })
    .subscribe(System.out::println);
    disposable.dispose();
    }

像這樣,在事件分發前,拿到Disposable物件,這樣你能在任意階段中斷 這個過程.

至此, 我們實現了基本的事件傳送和lambda呼叫,以及中斷功能.接下來我們需要開始新增 操作符了, 讓它真的能達到函式式呼叫的模樣!

新增 操作符(Map)

操作符的重點是, 你需要處理好上游傳遞下來的Disposable物件,以及下游待傳遞的Observer.

下面我們來實現map操作符的功能, 它可以將一個型別轉化為另一個型別.

  • 新增 Function介面,該介面接收一個型別的引數,並且返回另一個型別的值;
  • 新增 BasicObserver類,該類實現ObserverDisposable介面,用於傳遞上下游的資料;
  • 新增 ObservableMap類,該類繼承Observable,並且使用Function介面,實現型別轉換;內部類MapObserver 繼承自BasicObserver實現具體轉換邏輯;
  • 修改 Observable類,新增map操作符;
// Function.java
// 接收一個型別的引數,返回一個型別
public interface Function<T, R> {
    R apply(T t) throws Exception;
}
// BasicObserver.java
public abstract class BasicObserver<T, R> implements Observer<T>, Disposable {
    // 上游傳遞的Disposable物件
    private Disposable          upstream;
    // 下游接收的觀察者物件
    final   Observer<? super R> downstream;
    // 如果已經中斷,則無需下傳
    boolean done;
    BasicObserver(Observer<? super R> downstream) {
        this.downstream = downstream;
    }
    @Override
    public void onSubscribe(Disposable d) {
        // 接收上游的Disposable
        this.upstream = d;
        downstream.onSubscribe(this);
    }
    @Override
    public void onError(Throwable e) {
        if (done) return;
        done = true;
        downstream.onError(e);
    }
    @Override
    public void onComplete() {
        if (done) return;
        done = true;
        downstream.onComplete();
    }
    @Override
    public void dispose() {
        upstream.dispose();
    }
    @Override
    public boolean isDisposed() {
        return upstream.isDisposed();
    }
}
// ObservableMap.java
final class ObservableMap<T, U> extends Observable<U> {
    private final ObservableSource<T>              source;
    private final Function<? super T, ? extends U> function;
    ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        this.source = source;
        this.function = function;
    }
    @Override
    void subscribeActual(Observer<? super U> observer) {
        source.subscribe(new MapObserver<T, U>(observer, function));
    }
    static class MapObserver<T, U> extends BasicObserver<T, U> {
        final Function<? super T, ? extends U> mapper;
        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }
        @Override
        public void onNext(T t) {
            if (done) return;
            try {
                // 這裡實現具體的轉化,下游接收到轉化後的型別變數
                downstream.onNext(mapper.apply(t));
            } catch (Exception e) {
                onError(e);
            }
        }
    }
}
// Observable.java
public abstract class Observable<T> implements ObservableSource<T> {
    ...
    // map操作符
    public <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
        return new ObservableMap<>(this, mapper);
    }
}

實現好了map功能,我們來驗證一下:

    void mapTest() {
        Observable.create((ObservableOnSubscribe<String>) emitter -> {
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onComplete();
        })
        .map(s -> Integer.parseInt(s) * 10)
        .subscribe(System.out::println);
    }
    // 10
    // 20

哇!! 有點不可思議,已經做到這一步了,我們還差什麼呢? 沒錯,就是執行緒切換!!

PS : Rxjava中有很多的操作符, 我用其中比較典型的map來做示範,其他操作符,有興趣的可以自己手動來實現.

執行緒切換

rxjava中,自己實現了一套功能強大的執行緒池.配合操作符 observeOn,subscribeOn來進行執行緒切換.這裡就不對其進行展開,我們的重點是自己實現.

由於rxjava的執行緒池排程相當的複雜, 這裡為了方便演示,將只採用jdk自帶的執行緒池來做執行緒排程.下面我們來實現, rxjava中 observeOn操作符,以及Schedulers.io()的執行緒排程.

  • 新增Scheduler介面,定義了排程的方法,提交任務,移除任務,停止執行緒池;
  • 新增IOScheduler類,是Scheduler的具體實現,採用newCachedThreadPool提交任務和中斷任務;
  • 新增ObservableObserveOn類,繼承Observable,為observeOn操作符提供支援;內部類ObserveOnObserver,實現Observer,DisposableRunnable介面,run方法將攔截所有事件,將其作為任務提交給執行緒池執行,達到非同步的效果;
  • 修改Observable類,新增observeOn操作符;
// Scheduler.java
public interface Scheduler {
    void submit(Runnable runnable);
    void remove(Runnable runnable);
    void shutdown();
}
// IOScheduler
public class IOScheduler implements Scheduler {
    // 執行緒池
    private final ExecutorService       executor  = Executors.newCachedThreadPool();
    // 儲存Future物件,為了能夠中斷指定執行緒
    private final Map<Runnable, Future> futureMap = new ConcurrentHashMap<>();
    @Override
    public void submit(Runnable runnable) {
        Future future = futureMap.get(runnable);
        // 如果對應的任務正在執行,則無需再提交
        if (future != null && !future.isDone()) return;
        if (executor.isShutdown()) return;
        futureMap.put(runnable, executor.submit(runnable));
    }
    @Override
    public void remove(Runnable runnable) {
        Future future = futureMap.get(runnable);
        if (future == null) return;
        try {
            future.cancel(true);
        } catch (Exception ignored) {
        } finally {
            futureMap.remove(runnable);
        }
    }
    @Override
    public void shutdown() {
        if (!executor.isShutdown())
            executor.shutdown();
    }
}
// ObservableObserveOn.java
public final class ObservableObserveOn<T> extends Observable<T> {
    private final ObservableSource<T> source;
    private final Scheduler           scheduler;

    ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler) {
        this.source = source;
        this.scheduler = scheduler;
    }
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        source.subscribe(new ObserveOnObserver<>(observer, scheduler));
    }
    static final class ObserveOnObserver<T> implements Observer<T>, Disposable, Runnable {
        private final    Observer<? super T> downstream;
        private final    Scheduler           scheduler;
        private          Disposable          upstream;
        private volatile boolean             done;
        private volatile boolean             disposed;
        private          Queue<T>            queue = new LinkedList<>();
        private          Throwable           error;

        ObserveOnObserver(Observer<? super T> actual, Scheduler scheduler) {
            this.downstream = actual;
            this.scheduler = scheduler;
        }
        @Override
        public void onSubscribe(Disposable d) {
            upstream = d;
            downstream.onSubscribe(this);
        }
        @Override
        public void onNext(T t) {
            if (done) return;
            queue.offer(t);
            schedule();
        }
        @Override
        public void onError(Throwable t) {
            if (done) return;
            done = true;
            error = t;
            schedule();
        }
        @Override
        public void onComplete() {
            if (done) return;
            done = true;
            schedule();
        }
        @Override
        public void dispose() {
            if (!disposed) {
                disposed = true;
                upstream.dispose();
                scheduler.remove(this);
                queue.clear();
            }
        }
        @Override
        public boolean isDisposed() {
            return disposed;
        }
        // 提交任務
        void schedule() {
            scheduler.submit(this);
        }
        // 檢查事件是否已中斷,並作出相應的反饋
        boolean checkTerminated(boolean d, boolean empty, Observer<? super T> a) {
            if (disposed) {
                queue.clear();
                return true;
            }
            if (d) {
                Throwable e = error;
                if (e != null) {
                    disposed = true;
                    queue.clear();
                    a.onError(e);
                    scheduler.remove(this);
                    return true;
                } else if (empty) {
                    disposed = true;
                    a.onComplete();
                    scheduler.remove(this);
                    return true;
                }
            }
            return false;
        }
        @Override // 攔截事件傳遞,到run方法,run方法將由執行緒池執行
        public void run() {
            final Queue<T>            q = queue;
            final Observer<? super T> a = downstream;
            for (; ; ) {
                if (checkTerminated(done, q.isEmpty(), a)) return;
                for (; ; ) {
                    boolean d = done;
                    T       v;
                    try {
                        v = q.poll();
                    } catch (Throwable ex) {
                        disposed = true;
                        upstream.dispose();
                        q.clear();
                        a.onError(ex);
                        scheduler.remove(this);
                        return;
                    }
                    boolean empty = v == null;
                    if (checkTerminated(d, empty, a)) return;
                    if (empty) break;
                    a.onNext(v);
                }
            }
        }
    }
}
// Observable.java
public abstract class Observable<T> implements ObservableSource<T> {
    ...
    // 執行緒排程操作符
    public final Observable<T> observeOn(Scheduler scheduler) {
        return new ObservableObserveOn<>(this, scheduler);
    }
}

接下來我們來看示例:

    public void schedulerTest() throws InterruptedException {
        Observable.create((ObservableOnSubscribe<String>) emmit -> {
            System.out.println("emmit : " + Thread.currentThread().getName());
            emmit.onNext("1");
            emmit.onNext("2");
            emmit.onComplete();
        })
                .observeOn(Schedulers.io())
                .map(it -> {
                    int r = Integer.parseInt(it) * 10;
                    System.out.println(r + " : map : " + Thread.currentThread().getName());
                    return r;
                }).subscribe(it -> System.out.println(it + " : observer : " + Thread.currentThread().getName()),
                Functions.emptyConsumer(),
                () -> System.out.println("onCompleted.... " + Thread.currentThread().getName()));
        TimeUnit.SECONDS.sleep(1);
    }
emmit : main
10 : map : pool-1-thread-1
10 : observer : pool-1-thread-1
20 : map : pool-1-thread-1
20 : observer : pool-1-thread-1
onCompleted.... pool-1-thread-1

可以看到 observeOn的所有下游事件,都在新的執行緒中執行了!!至此,執行緒排程的部分功能,我們也粗略的實現了!

總結

如果,你從開始看到現在, 我們已經自己實現了rxjava的一個基本使用操作了,編寫了10來個類,其中大部分都是介面,寫了500多行的程式碼.其中涉及rxjava中事件分發,lambda呼叫,取消和中斷,map操作符,io執行緒切換,這一完整的流程.

rxjava 提供了豐富的 操作符, 和 各種的執行緒切換模型, 我們在理解其原理的情況下,都可以自己來實現.

rxjava中 RxJavaPlugins使用代理的思想來插入全域性資源管理,以及使用Backpressure(背壓)來控制資料流的思想,我們都可以學習和借鑑!

我們在學習過程中,可以根據原始碼,分解其中的知識點,逐步消化,甚至自己動手來實現它, 來達到深入理解的目的.

最後,趕緊動手編寫吧!!!

引用

  1. RxJava: Reactive Extensions for the JVM


相關文章