Rxjava(变换类)--FlatMap2

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))的数量

则不会有问题




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值