Rxjava(变换类)--FlatMap2
来源:互联网 发布:大数据对零售业 编辑:程序博客网 时间:2024/06/06 13:20
demo
ArrayList aa= new ArrayList<>(Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10)); Observable.from(aa).flatMap(new Func1<Integer, Observable<Integer>>() { @Override public Observable<Integer> call(Integer number) { return Observable.just(number * number).subscribeOn(Schedulers.from(JobExecutor.getInstance())); } }).subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.print(integer + ", "); } });
public final <R> Observable<R> flatMap(Func1<? super T, ? extends Observable<? extends R>> func) { if (getClass() == ScalarSynchronousObservable.class) { return ((ScalarSynchronousObservable<T>)this).scalarFlatMap(func); } return merge(map(func)); }
这里会走下面的merge,merge之前会调用map生成一个Observable ,我们看一下map是怎么生成Observable 的
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) { return create(new OnSubscribeMap<T, R>(this, func)); }
public OnSubscribeMap(Observable<T> source, Func1<? super T, ? extends R> transformer) { this.source = source; this.transformer = transformer; }这里的transformer就是我们demo里面flatMap的参数
再回到merge
public static <T> Observable<T> merge(Observable<? extends Observable<? extends T>> source) { if (source.getClass() == ScalarSynchronousObservable.class) { return ((ScalarSynchronousObservable<T>)source).scalarFlatMap((Func1)UtilityFunctions.identity()); } return source.lift(OperatorMerge.<T>instance(false)); }
这里不是ScalarSynchronousObservable,走下面一个分支
lift函数要求传进去一个Operator函数,这里用的是OperatorMerge.<T>instance(false)
public static <T> OperatorMerge<T> instance(boolean delayErrors) { if (delayErrors) { return (OperatorMerge<T>)HolderDelayErrors.INSTANCE; } return (OperatorMerge<T>)HolderNoDelay.INSTANCE; }
delayErrors为false,所以这里返回的是(OperatorMerge<T>)HolderNoDelay.INSTANCE
static final OperatorMerge<Object> INSTANCE = new OperatorMerge<Object>(false, Integer.MAX_VALUE);
回到lift函数
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) { return create(new OnSubscribeLift<T, R>(onSubscribe, operator)); }这里创建了一个OnSubscribeLift,传进来了前面的operator以及Observable本身的onSubscribe(前面的OnSubscribeMap)
目前OnSubscribe的关系
然后调用subscribe,最先调用的是OnSubscribeLift的call
public void call(Subscriber<? super R> o) { try { Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o); try { // new Subscriber created and being subscribed with so 'onStart' it st.onStart(); parent.call(st); } catch (Throwable e) { // localized capture of errors rather than it skipping all operators // and ending up in the try/catch of the subscribe method which then // prevents onErrorResumeNext and other similar approaches to error handling Exceptions.throwIfFatal(e); st.onError(e); } } catch (Throwable e) { Exceptions.throwIfFatal(e); // if the lift function failed all we can do is pass the error to the final Subscriber // as we don't have the operator available to us o.onError(e); } }这里的parent即为OnSubsuribeMap,operator就是前面的OperatorMerge,o是SafeSubscriber(观察者),也即对我们demo中subscribe中参数做了一个封装。
我们看一下OperatorMerge的call
public Subscriber<Observable<? extends T>> call(final Subscriber<? super T> child) { MergeSubscriber<T> subscriber = new MergeSubscriber<T>(child, delayErrors, maxConcurrent); MergeProducer<T> producer = new MergeProducer<T>(subscriber); subscriber.producer = producer; child.add(subscriber); child.setProducer(producer); return subscriber; }
创建了一个MergeSubscriber,child是我们的观察者,delayErrors是false,maxConcurrent是Integer.MAX_VALUE
然后以创建的MergeSubscriber创建了一个MergeProducer,把subscriber的producer设置为刚创建的producer,然后调用child的setProducer
我们先看一下MergeSubscriber的构造函数
public MergeSubscriber(Subscriber<? super T> child, boolean delayErrors, int maxConcurrent) { this.child = child; this.delayErrors = delayErrors; this.maxConcurrent = maxConcurrent; this.innerGuard = new Object(); this.innerSubscribers = EMPTY; if (maxConcurrent == Integer.MAX_VALUE) { scalarEmissionLimit = Integer.MAX_VALUE; request(Long.MAX_VALUE); } else { scalarEmissionLimit = Math.max(1, maxConcurrent >> 1); request(maxConcurrent); } }
这里走if语句
protected final void request(long n) { if (n < 0) { throw new IllegalArgumentException("number requested cannot be negative: " + n); } // if producer is set then we will request from it // otherwise we increase the requested count by n Producer producerToRequestFrom; synchronized (this) { if (producer != null) { producerToRequestFrom = producer; } else { addToRequested(n); return; } } // after releasing lock (we should not make requests holding a lock) producerToRequestFrom.request(n); }producer为null,走else分支
private void addToRequested(long n) { if (requested == NOT_SET) { requested = n; } else { final long total = requested + n; // check if overflow occurred if (total < 0) { requested = Long.MAX_VALUE; } else { requested = total; } } }
这里requested == NOT_SET,走if语句,n = Long.MAX_VALUE
MergeProducer的构造函数很简单
public MergeProducer(MergeSubscriber<T> subscriber) { this.subscriber = subscriber; }接着我们看一下setProducer,由前面的文章分析我们可以知道最终会调用producer的request
这里的producer是MergeProducer
public void request(long n) { if (n > 0) { if (get() == Long.MAX_VALUE) { return; } BackpressureUtils.getAndAddRequest(this, n); subscriber.emit(); } else if (n < 0) { throw new IllegalArgumentException("n >= 0 required"); } }n的值为Long.MAX_VALUE
这里走if分支调用 subscriber.emit();
void emit() { synchronized (this) { if (emitting) { missed = true; return; } emitting = true; } emitLoop(); }
开始emitting为false,所以这里设置emitting为true,接着调用emitLoop
void emitLoop() { boolean skipFinal = false; try { final Subscriber<? super T> child = this.child; for (;;) { // eagerly check if child unsubscribed or we reached a terminal state. if (checkTerminate()) { skipFinal = true; return; } Queue<Object> svq = queue; long r = producer.get(); boolean unbounded = r == Long.MAX_VALUE; // count the number of 'completed' sources to replenish them in batches int replenishMain = 0; // try emitting as many scalars as possible if (svq != null) { for (;;) { int scalarEmission = 0; Object o = null; while (r > 0) { o = svq.poll(); // eagerly check if child unsubscribed or we reached a terminal state. if (checkTerminate()) { skipFinal = true; return; } if (o == null) { break; } T v = NotificationLite.getValue(o); // if child throws, report bounce it back immediately try { child.onNext(v); } catch (Throwable t) { if (!delayErrors) { Exceptions.throwIfFatal(t); skipFinal = true; unsubscribe(); child.onError(t); return; } getOrCreateErrorQueue().offer(t); } replenishMain++; scalarEmission++; r--; } if (scalarEmission > 0) { if (unbounded) { r = Long.MAX_VALUE; } else { r = producer.produced(scalarEmission); } } if (r == 0L || o == null) { break; } } } /* * We need to read done before innerSubscribers because innerSubscribers are added * before done is set to true. If it were the other way around, we could read an empty * innerSubscribers, get paused and then read a done flag but an async producer * might have added more subscribers between the two. */ boolean d = done; // re-read svq because it could have been created // asynchronously just before done was set to true. svq = queue; // read the current set of inner subscribers InnerSubscriber<?>[] inner = innerSubscribers; int n = inner.length; // check if upstream is done, there are no scalar values // and no active inner subscriptions if (d && (svq == null || svq.isEmpty()) && n == 0) { Queue<Throwable> e = errors; if (e == null || e.isEmpty()) { child.onCompleted(); } else { reportError(); } skipFinal = true; return; } boolean innerCompleted = false; if (n > 0) { // let's continue the round-robin emission from last location long startId = lastId; int index = lastIndex; // in case there were changes in the array or the index // no longer points to the inner with the cached id if (n <= index || inner[index].id != startId) { if (n <= index) { index = 0; } // try locating the inner with the cached index int j = index; for (int i = 0; i < n; i++) { if (inner[j].id == startId) { break; } // wrap around in round-robin fashion j++; if (j == n) { j = 0; } } // if we found it again, j will point to it // otherwise, we continue with the replacement at j index = j; lastIndex = j; lastId = inner[j].id; } int j = index; // loop through all sources once to avoid delaying any new sources too much for (int i = 0; i < n; i++) { // eagerly check if child unsubscribed or we reached a terminal state. if (checkTerminate()) { skipFinal = true; return; } @SuppressWarnings("unchecked") InnerSubscriber<T> is = (InnerSubscriber<T>)inner[j]; Object o = null; for (;;) { int produced = 0; while (r > 0) { // eagerly check if child unsubscribed or we reached a terminal state. if (checkTerminate()) { skipFinal = true; return; } RxRingBuffer q = is.queue; if (q == null) { break; } o = q.poll(); if (o == null) { break; } T v = NotificationLite.getValue(o); // if child throws, report bounce it back immediately try { child.onNext(v); } catch (Throwable t) { skipFinal = true; Exceptions.throwIfFatal(t); try { child.onError(t); } finally { unsubscribe(); } return; } r--; produced++; } if (produced > 0) { if (!unbounded) { r = producer.produced(produced); } else { r = Long.MAX_VALUE; } is.requestMore(produced); } // if we run out of requests or queued values, break if (r == 0 || o == null) { break; } } boolean innerDone = is.done; RxRingBuffer innerQueue = is.queue; if (innerDone && (innerQueue == null || innerQueue.isEmpty())) { removeInner(is); if (checkTerminate()) { skipFinal = true; return; } replenishMain++; innerCompleted = true; } // if we run out of requests, don't try the other sources if (r == 0) { break; } // wrap around in round-robin fashion j++; if (j == n) { j = 0; } } // if we run out of requests or just completed a round, save the index and id lastIndex = j; lastId = inner[j].id; } if (replenishMain > 0) { request(replenishMain); } // if one or more inner completed, loop again to see if we can terminate the whole stream if (innerCompleted) { continue; } // in case there were updates to the state, we loop again synchronized (this) { if (!missed) { skipFinal = true; emitting = false; break; } missed = false; } } } finally { if (!skipFinal) { synchronized (this) { emitting = false; } } } }
这个函数比较长
返回OnSubscribeLift的call函数,这里返回的st为MergeSubscriber
接着调用
parent.call(st);这里parent从图中可以看出是OnSubscribeMap,调用它的call函数
public void call(final Subscriber<? super R> o) { MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer); o.add(parent); source.unsafeSubscribe(parent); }这里新建一个MapSubscriber,transformer就是我们demo中传给flapmap的回调函数
这里的source为
调用unsafeSubscribe最终会调用到source的call函数,也即OnSubscribeFromIterable的call
public void call(final Subscriber<? super T> o) { Iterator<? extends T> it; boolean b; try { it = is.iterator(); b = it.hasNext(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } if (!o.isUnsubscribed()) { if (!b) { o.onCompleted(); } else { o.setProducer(new IterableProducer<T>(o, it)); } } }由于是第一次进来,且iterator中有9个值,这里b为true,最终调用setProducer,创建了一个IterableProducer
IterableProducer(Subscriber<? super T> o, Iterator<? extends T> it) { this.o = o; this.it = it; }
public void setProducer(Producer p) { actual.setProducer(p); }这里的actual就是前面的MergeSubscriber
最终会调用producer的request,这里的producer为IterableProducer
@Override public void request(long n) { if (get() == Long.MAX_VALUE) { // already started with fast-path return; } if (n == Long.MAX_VALUE && compareAndSet(0, Long.MAX_VALUE)) { fastPath(); } else if (n > 0 && BackpressureUtils.getAndAddRequest(this, n) == 0L) { slowPath(n); } }这里走fastPath
void fastPath() { // fast-path without backpressure final Subscriber<? super T> o = this.o; final Iterator<? extends T> it = this.it; for (;;) { if (o.isUnsubscribed()) { return; } T value; try { value = it.next(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } o.onNext(value); if (o.isUnsubscribed()) { return; } boolean b; try { b = it.hasNext(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } if (!b) { if (!o.isUnsubscribed()) { o.onCompleted(); } return; } } }
获取值,这里为2,接着调用onNext
o为MapSubscriber
@Override public void onNext(T t) { R result; try { result = mapper.call(t); } catch (Throwable ex) { Exceptions.throwIfFatal(ex); unsubscribe(); onError(OnErrorThrowable.addValueAsLastCause(ex, t)); return; } actual.onNext(result); }这里的mapper就是我们demo中传给flapmap的回调函数
public Observable<Integer> call(Integer number) { return Observable.just(number * number).subscribeOn(Schedulers.from(JobExecutor.getInstance())); }这里最终会调用到ScalarSynchronousObservable的scalarScheduleOn
public Observable<T> scalarScheduleOn(final Scheduler scheduler) { Func1<Action0, Subscription> onSchedule; if (scheduler instanceof EventLoopsScheduler) { final EventLoopsScheduler els = (EventLoopsScheduler) scheduler; onSchedule = new Func1<Action0, Subscription>() { @Override public Subscription call(Action0 a) { return els.scheduleDirect(a); } }; } else { onSchedule = new Func1<Action0, Subscription>() { @Override public Subscription call(final Action0 a) { final Scheduler.Worker w = scheduler.createWorker(); w.schedule(new Action0() { @Override public void call() { try { a.call(); } finally { w.unsubscribe(); } } }); return w; } }; } return create(new ScalarAsyncOnSubscribe<T>(t, onSchedule)); }走else分支,返回一个ScalarAsyncOnSubscribe
回到MapSubscriber的onNext,接着调用
actual.onNext(result);actual是MergeSubscriber
public void onNext(Observable<? extends T> t) { if (t == null) { return; } if (t == Observable.empty()) { emitEmpty(); } else if (t instanceof ScalarSynchronousObservable) { tryEmit(((ScalarSynchronousObservable<? extends T>)t).get()); } else { InnerSubscriber<T> inner = new InnerSubscriber<T>(this, uniqueId++); addInner(inner); t.unsafeSubscribe(inner); emit(); } }t是ScalarAsyncOnSubscribe
走最后一个else分支,新建一个InnerSubscriber,uniqueId开始为0,this是MergeSubscriber
public InnerSubscriber(MergeSubscriber<T> parent, long id) { this.parent = parent; this.id = id; }
unsafeSubscribe最终调用t的call
@Override public void call(Subscriber<? super T> s) { s.setProducer(new ScalarAsyncProducer<T>(s, value, onSchedule)); }这里创建一个ScalarAsyncProducer,value为2,onSchedule是前面创建的一个回调
setProducer最终调用ScalarAsyncProducer的request
public void request(long n) { if (n < 0L) { throw new IllegalArgumentException("n >= 0 required but it was " + n); } if (n != 0 && compareAndSet(false, true)) { actual.add(onSchedule.call(this)); } }这里最关键的是调用onSchedule.call(this)
public Subscription call(final Action0 a) { final Scheduler.Worker w = scheduler.createWorker(); w.schedule(new Action0() { @Override public void call() { try { a.call(); } finally { w.unsubscribe(); } } }); return w; }这里会调用schedule启动一个线程去执行操作,线程最终会调用schedule中的回调函数执行具体的任务,这里我们依次回到OnSubscribeFromIterable的fastPath
void fastPath() { // fast-path without backpressure final Subscriber<? super T> o = this.o; final Iterator<? extends T> it = this.it; for (;;) { if (o.isUnsubscribed()) { return; } T value; try { value = it.next(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } o.onNext(value); if (o.isUnsubscribed()) { return; } boolean b; try { b = it.hasNext(); } catch (Throwable ex) { Exceptions.throwOrReport(ex, o); return; } if (!b) { if (!o.isUnsubscribed()) { o.onCompleted(); } return; } } }b为false,继续下一个循环....
我们再看一下线程执行的回调
public void call() { try { a.call(); } finally { w.unsubscribe(); } }
这里的a是ScalarAsyncProducer,我们看一下他的call
public void call() { Subscriber<? super T> a = actual; if (a.isUnsubscribed()) { return; } T v = value; try { a.onNext(v); } catch (Throwable e) { Exceptions.throwOrReport(e, a, v); return; } if (a.isUnsubscribed()) { return; } a.onCompleted(); }这里a是InnerSubscriber
public void onNext(T t) { parent.tryEmit(this, t); }
parent为MergeSubscriber
void tryEmit(InnerSubscriber<T> subscriber, T value) { boolean success = false; long r = producer.get(); if (r != 0L) { synchronized (this) { // if nobody is emitting and child has available requests r = producer.get(); if (!emitting && r != 0L) { emitting = true; success = true; } } } if (success) { RxRingBuffer subscriberQueue = subscriber.queue; if (subscriberQueue == null || subscriberQueue.isEmpty()) { emitScalar(subscriber, value, r); } else { queueScalar(subscriber, value); emitLoop(); } } else { queueScalar(subscriber, value); emit(); } }success = true,调用emitScalar(subscriber, value, r)
protected void emitScalar(InnerSubscriber<T> subscriber, T value, long r) { boolean skipFinal = false; try { try { child.onNext(value); } catch (Throwable t) { if (!delayErrors) { Exceptions.throwIfFatal(t); skipFinal = true; subscriber.unsubscribe(); subscriber.onError(t); return; } getOrCreateErrorQueue().offer(t); } if (r != Long.MAX_VALUE) { producer.produced(1); } subscriber.requestMore(1); // check if some state changed while emitting synchronized (this) { skipFinal = true; if (!missed) { emitting = false; return; } missed = false; } } finally { if (!skipFinal) { synchronized (this) { emitting = false; } } } /* * In the synchronized block below request(1) we check * if there was a concurrent emission attempt and if there was, * we stay in emission mode and enter the emission loop * which will take care all the queued up state and * emission possibilities. */ emitLoop(); }
child为SafeSubscriber,调用它的onNext最终会调用到我们demo中的onNext方法
public void call(Integer integer) { System.out.print(integer + ", "); }这样就执行完了
由前面的分析可知,由于在flatMap中加了subscribeOn切换线程,而这些线程的启动是几乎是同时启动的,所以无法保证按照我们传递的参数(Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10))的顺序执行
public class JobExecutor implements Executor { private static class LazyHolder { private static final JobExecutor INSTANCE = new JobExecutor(); } public static JobExecutor getInstance() { return LazyHolder.INSTANCE; } private static final int INITIAL_POOL_SIZE = 3; private static final int MAX_POOL_SIZE = 5; // Sets the amount of time an idle thread waits before terminating private static final int KEEP_ALIVE_TIME = 10; // Sets the Time Unit to seconds private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS; private final BlockingQueue<Runnable> workQueue; private final ThreadPoolExecutor threadPoolExecutor; private JobExecutor() { this.workQueue = new LinkedBlockingQueue<>(); this.threadPoolExecutor = new ThreadPoolExecutor(INITIAL_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, workQueue); } @Override public void execute(Runnable runnable) { if (runnable == null) { throw new IllegalArgumentException("Runnable to execute cannot be null"); } threadPoolExecutor.execute(runnable); }}
如果把MAX_POOL_SIZE改为大于
Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10))的数量
则不会有问题
- Rxjava(变换类)--FlatMap2
- Rxjava(变换类)--map
- Rxjava(变换类)--FlatMap
- Rxjava(变换类)-concatMap
- Rxjava(变换类)-Buffer
- Rxjava(变换类)-scan
- Rxjava(变换类)-GroupBy
- Rxjava(变换类)-Window
- RxJava变换
- RxAndroid与RxJava 变换
- RxJava-变换操作
- RxJava的变换操作
- RXJava 变换操作
- RxJava系列之二 变换类操作符详解1
- RxJava使用(四)变换
- RxJava操作符(2)-变换
- Rxjava源码(二)-----变换
- RxJava使用(四)变换
- HDU 3695 Computer Virus on Planet Pandora AC自动机
- ReactiveCocoa之RAC过滤(八)
- 浅拷贝深拷贝
- 留言板
- SPOJ 3943 Nested Dolls
- Rxjava(变换类)--FlatMap2
- Android之QQ聊天气泡对话实现
- lower_bound/upper_bound(STL)
- 从源码上深度剖析View invalidate 、 postInvalidate、requestLayout
- Java小程序祝国庆快乐
- SixChat交友社区 高仿微信朋友圈 PHP OR JSP
- Docker - Brief intro
- Lock - java-util-concurrent
- 选择