RxJava全家桶--Rxjava源码分析

前沿

RxJava现在应用范围很广,可以和retrofit,okhttp结合实现网络请求,可以和GreenDao结合实现数据库功能,也能应用开发框架MVP,MVVM有很好的兼容性,这个也符合现在的大环境和很火热的概念,叫做生态。

一.RxJava特点

RxJava火热的原因归结于4点:

1.流式操作

2.多元化的操作符

3.线程调度

4.背压

第二点不是本文的初衷,但是我浏览相关资料的时候发现一篇比较好的文章:RxJava2.x使用以及操作符详解

第四点发现一个作者写的好,就直接安利他的文章

二.流式操作源码分析

1.使用栗子

        Observable.create(
                new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter)
                            throws Exception {}
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {}
                    @Override
                    public void onNext(Integer integer) {}
                    @Override
                    public void onError(Throwable e) {}
                    @Override
                    public void onComplete() {}
                });

2.源码时序图

RxJava抛开publisher创建的过程,遵循观察者模式publisher.subscribe(observer)

(01~07)装饰模式生成ObservableObserveOn对象

(08~22)观察者模式发布者订阅观察者

(23~28)发送消息

2.1 ObservableObserveOn对象生成

Rxjava存在3种类型的发布者:

(1)不切换线程的发布者ObservableCreate

(2)指定发布者运行在某一线程的发布者ObservableSubscribeOn

(3)指定观察者运行在某一线程的发布者ObservableObserveOn

这边作者借鉴了装饰模式的思路,将把类的核心职责和装饰功能区隔离,进行代码的解耦。

按照装饰顺序:

(1)将传入发布者匿名内部类,封装成核心类ObservableCreate

(2)将核心类ObservableCreate,装饰成发布者运行在IO线程的装饰类ObservableSubscribeOn

(3)将装饰类ObservableSubscribeOn,装饰成观察者运行在主线程的装饰类ObservableObserverOn

2.2 观察者模式发布者订阅观察者

上述生成的ObservableObserverOn.subscribe(Observer) 生成对象按照下图中从上到下,subscribe是按照下图从下到上。

currentThread:调用者所在线程

(1)根据设定的线程(主线程)创建线程任务

(2)实例化ObserveOnObserver对象

(3)执行ObservableSubscribeOn.subscribe(ObserveOnObserver)

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();

            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }
}

currentThread:调用者所在线程

(1)使用ObserveOnObserver创建SubscribeOnObserver对象

(2)回调给下游观察者onSubscribe

(3)线程调度使用指定发布者运行的线程(IO线程)执行

(4)currentThread= IO线程,执行ObservableCreate.subscribe(SubscribeOnObserver)

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    @Override
    public void subscribeActual(final Observer<? super T> observer) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);

        observer.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }
    @Override
    public void run() {
        System.err.println("Rxjava ObservableSubscribeOn Thread.currentThread() = " + Thread.currentThread().getId());
        source.subscribe(parent);
    }
}

currentThread:IO线程

(1)使用SubscribeOnObserver创建CreateEmitter发射器对象

(2)回调SubscribeOnObserver onSubscribe

(3)回调上游发布者方法subscribe

public final class ObservableCreate<T> extends Observable<T> {
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
}

2.3发射消息

currentThread:IO线程

(1)外部调用类获得发射器对象实例ObservableEmitter,执行OnNext方法

(2)调用SubscribeOnObserver.onNext(t)

public final class ObservableCreate<T> extends Observable<T> {
	static final class CreateEmitter<T>
		extends AtomicReference<Disposable>
		implements ObservableEmitter<T>, Disposable {
        	@Override
        	public void onNext(T t) {
            	if (t == null) {
                	onError(new NullPointerException("onNext called with null. Null values are " +
                        	"generally not allowed in 2.x operators and sources."));
                	return;
            	}
            	if (!isDisposed()) {
                	observer.onNext(t);
            	}
        	}
	}
}

currentThread:IO线程

(1)调用ObserveOnObserver.onNext(t)

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
	static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
		@Override
        	public void onNext(T t) {
            	downstream.onNext(t);
        	}
	}
}

currentThread:IO线程

(1)使用线程调度切换到观察者指定的线程(主线程)

(2)currentThread=mainThread,回调下游观察者方法onNext

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
	static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    	implements Observer<T>, Runnable {
		@Override
        	public void onNext(T t) {
			if (done) {
				return;
			}

			if (sourceMode != QueueDisposable.ASYNC) {
			      queue.offer(t);
			}
			schedule();
        	}
		@Override
        	public void run() {
            		drainNormal();
        	}
		void drainNormal() {
            		a.onNext(v);
    
        	}		
	}
}

这里就完成了发布者运行在IO线程,观察者在主线程的流程。接下来在看看线程调度。

2.4策略模式线程调度

结合EventBus线程操作发现,两者有很多相同点,从业务上讲都有线程调度,都有并发的风险,都有开辟大量线程的可能,从技术上讲两者都采用了线程池,清理缓存线程,超时机制,策略模式。技术方面最大的不同,EventBus采用锁来解决并发,RxJava使用是原子类。

(1)创建线程池运行并线程任务

(2)利用已有线程池运行线程任务

2.5背压

背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略。比较Observable,发现装饰模式生成发布者,策略模式线程调度没有变化。RxJava2.0提供了5种背压策略,区别在于发射器执行onNext时的逻辑处理

Flowable
        .create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> e) throws Exception {
                for (int i = 1; i <= 130; i++) {
			e.onNext(i);
		}
            }
        }, BackpressureStrategy.MISSING/*ERROR*//*BUFFER*//*DROP*//*LATEST*/)
        .subscribeOn(Schedulers.newThread())
        .observeOn(Schedulers.newThread())
        .subscribe(new Subscriber<Integer>() {

            @Override
            public void onSubscribe(Subscription s) {s.request(Long.MAX_VALUE);}

            @Override
            public void onNext(Integer integer) {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.err.println("NoOverflowBaseAsyncEmitter onNext = " + integer);
            }

            @Override
            public void onError(Throwable t) {
                System.err.println("NoOverflowBaseAsyncEmitter onError = " + t);
            }

            @Override
            public void onComplete() {
            }
        });

(1)MISSING

和ObservableEmitter没什么区别,直接把收到范形消息经过线程调度传给下游观察者。不过在这边方法结尾加了一个循环目的是为了保证当前可执行的消息数目要等于最大可发送的减去目前已经发送的。

static final class MissingEmitter<T> extends BaseEmitter<T> {
        @Override
        public void onNext(T t) {
            if (isCancelled()) {
                return;
            }

            if (t != null) {
                downstream.onNext(t);
            } else {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }

            for (;;) {
                long r = get();
                if (r == 0L || compareAndSet(r, r - 1)) {
                    return;
                }
            }
        }
}

(2)ERROR

这边实现类似于倒计时的原理,ErrorAsyncEmitter是继承AtomicLong的,初始化绑定时调用request方法,设置初始值为128。每执行一次方法就调用 BackpressureHelper.produced设置当前还剩余可发送数量。如果为0,发送OnError消息抛出MissingBackpressureException异常。

static final class ErrorAsyncEmitter<T> extends NoOverflowBaseAsyncEmitter<T> {

	@Override
        public final void onNext(T t) {
            if (isCancelled()) {
                return;
            }

            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }

            if (get() != 0) {
                System.err.println("NoOverflowBaseAsyncEmitter get() = " + get());
                downstream.onNext(t);
                BackpressureHelper.produced(this, 1);
            } else {
                System.err.println("NoOverflowBaseAsyncEmitter onOverflow");
                onOverflow();
            }
        }

        @Override
        void onOverflow() {
            onError(new MissingBackpressureException("create: could not emit value due to lack of requests"));
        }
}

(3)DROP

这个发现和ERROR没什么区别,惟一的区别,计数器为0了,ERROR会给下游抛出onError异常,DROP就什么也不做

static final class DropAsyncEmitter<T> extends NoOverflowBaseAsyncEmitter<T> {

	@Override
        public final void onNext(T t) {
            if (isCancelled()) {
                return;
            }

            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }

            if (get() != 0) {
                System.err.println("NoOverflowBaseAsyncEmitter get() = " + get());
                downstream.onNext(t);
                BackpressureHelper.produced(this, 1);
            } else {
                System.err.println("NoOverflowBaseAsyncEmitter onOverflow");
                onOverflow();
            }
        }

        @Override
        void onOverflow() {
        }
}

(4)LATEST

这个策略很有意思,就像你有一张额度为128的信用卡,但是你保持一笔账单消费1块钱,直到花了130。透支了2块钱。然后你收到账单了,累计账单达到96选择分期还款96。然后银行到账你的还款了,然后你又有额度了,你就可以接着去花了。这边选择这个策略前128个会保证正常返回,中间的就不能保证了,要看下游什么时候调用upstream.request(e),但是会保证最后一条数据返回给你。

这边和ERROR一样倒计时128,为0时就不再执行while循环任务。

public final class FlowableCreate<T> extends Flowable<T> {
	static final class LatestAsyncEmitter<T> extends BaseEmitter<T> {

		@Override
		public void onNext(T t) {
		    if (done || isCancelled()) {
		        return;
		    }

		    if (t == null) {
		        onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
		        return;
		    }
		    queue.set(t);
		    drain();
		}

		void drain() {
		    if (wip.getAndIncrement() != 0) {
		        return;
		    }

		    int missed = 1;
		    final Subscriber<? super T> a = downstream;
		    final AtomicReference<T> q = queue;

		    for (;;) {
		        long r = get();
		        long e = 0L;
		        while (e != r) {
		            ...
		        }
		    }
		}
	    }

	}
}

发送计数,达到96就告诉上游LatestAsyncEmitter调用BackpressureHelper.add(this, n);将0修改成96。让drain的while循环可以接着执行。

public final class FlowableObserveOn<T> extends AbstractFlowableWithUpstream<T, T> {
    static final class ObserveOnSubscriber<T> extends BaseObserveOnSubscriber<T>
    implements FlowableSubscriber<T> {

        @Override
        public final void onNext(T t) {
            if (done) {
                return;
            }
            if (sourceMode == ASYNC) {
                trySchedule();
                return;
            }
            if (!queue.offer(t)) {
                upstream.cancel();

                error = new MissingBackpressureException("Queue is full?!");
                done = true;
            }
            trySchedule();
        }

	@Override
        void runAsync() {
            int missed = 1;

            final Subscriber<? super T> a = downstream;
            final SimpleQueue<T> q = queue;
            long e = produced;

            for (;;) {

                long r = requested.get();
                while (e != r) {
                    ...
                    if (e == limit) {
                        if (r != Long.MAX_VALUE) {
                            r = requested.addAndGet(-e);
                        }
                        upstream.request(e);
                        e = 0L;
                    }
                }
            }
        }
    }
}

(5)BUFFER

这个策略是先将事件存入AtomicReferenceArray中。这个数组的长度是129中然后在从数组中取出来,返回给下游,这边的index和时事件都是存放原子类中,防止并发问题。

public final class FlowableCreate<T> extends Flowable<T> {
    static final class BufferAsyncEmitter<T> extends BaseEmitter<T> {
	@Override
        public void onNext(T t) {
            if (done || isCancelled()) {
                return;
            }

            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            queue.offer(t);
            drain();
        }

	void drain() {
            ...
            final Subscriber<? super T> a = downstream;
            final SpscLinkedArrayQueue<T> q = queue;

            for (;;) {
                long r = get();
                long e = 0L;
                while (e != r) {
                    boolean d = done;
                    T o = q.poll();
		    ...
                    boolean empty = o == null;
                    if (empty) {
                        break;
                    }

                    a.onNext(o);

                    e++;
                }
		...
            }
        }
    }
}

很多人说用这个数组是无限大的可以一直往里面存,会导致oom。但是我看源码发现这个数组长度是129,不会是无限大的。所以我怀疑他们说的不对,或者源码更新了。但是这么说的人太多了,我只能根据我看的认为这个不会导致oom。

如果插入的index小于127,那么直接插入到数组中。

如果大于126,先利用与运算得出当前index与127的偏移量,然后去找当前索引是否含有值,发送完事件给下游之后会将当前index对应的事件置为null。所以可以继续往下存。

public final class SpscLinkedArrayQueue<T> implements SimplePlainQueue<T> {
    @Override
    public boolean offer(final T e) {
        if (null == e) {
            throw new NullPointerException("Null is not a valid element");
        }
        // local load of field to avoid repeated loads after volatile reads
        final AtomicReferenceArray<Object> buffer = producerBuffer;
        final long index = lpProducerIndex();
        final int mask = producerMask;
        final int offset = calcWrappedOffset(index, mask);
        if (index < producerLookAhead) {
            return writeToQueue(buffer, e, index, offset);
        } else {
            final int lookAheadStep = producerLookAheadStep;
            // go around the buffer or resize if full (unless we hit max capacity)
            int lookAheadElementOffset = calcWrappedOffset(index + lookAheadStep, mask);
            if (null == lvElement(buffer, lookAheadElementOffset)) { // LoadLoad
                producerLookAhead = index + lookAheadStep - 1; // joy, there's plenty of room
                return writeToQueue(buffer, e, index, offset);
            } else if (null == lvElement(buffer, calcWrappedOffset(index + 1, mask))) { // buffer is not full
                return writeToQueue(buffer, e, index, offset);
            } else {
                resize(buffer, index, offset, e, mask); // add a buffer and link old to new
                return true;
            }
        }
    }
    @Override
    public T poll() {
        // local load of field to avoid repeated loads after volatile reads
        final AtomicReferenceArray<Object> buffer = consumerBuffer;
        final long index = lpConsumerIndex();
        final int mask = consumerMask;
        final int offset = calcWrappedOffset(index, mask);
        final Object e = lvElement(buffer, offset);// LoadLoad
        boolean isNextBuffer = e == HAS_NEXT;
        if (null != e && !isNextBuffer) {
            soElement(buffer, offset, null);// StoreStore
            soConsumerIndex(index + 1);// this ensures correctness on 32bit platforms
            return (T) e;
        } else if (isNextBuffer) {
            return newBufferPoll(lvNextBufferAndUnlink(buffer, mask + 1), index, mask);
        }

        return null;
    }

}

结尾在附上Flowable调用的时序图

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值