Rxjava(变换类)-concatMap

来源:互联网 发布:ansoft maxwell软件 编辑:程序博客网 时间:2024/06/07 09:41

demo

        Observable.from(aa).concatMap(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 + ", ");            }        });

看下contctMap

    public final <R> Observable<R> concatMap(Func1<? super T, ? extends Observable<? extends R>> func) {        if (this instanceof ScalarSynchronousObservable) {            ScalarSynchronousObservable<T> scalar = (ScalarSynchronousObservable<T>) this;            return scalar.scalarFlatMap(func);        }        return create(new OnSubscribeConcatMap<T, R>(this, func, 2, OnSubscribeConcatMap.IMMEDIATE));    }

这里 如果 是 ScalarSynchronousObservable 就跟flatMap一样,我们看下不是ScalarSynchronousObservable类型

这里会创建一个OnSubscribeConcatMap,这里会把Func1保存到mapper,另外两个参数是 2, OnSubscribeConcatMap.IMMEDIATE

然后后面subscribe的时候会调用OnSubscribeConcatMap的call函数,我们看一下它的实现

public void call(Subscriber<? super R> child) {        Subscriber<? super R> s;        if (delayErrorMode == IMMEDIATE) {            s = new SerializedSubscriber<R>(child);        } else {            s = child;        }        final ConcatMapSubscriber<T, R> parent = new ConcatMapSubscriber<T, R>(s, mapper, prefetch, delayErrorMode);        child.add(parent);        child.add(parent.inner);        child.setProducer(new Producer() {            @Override            public void request(long n) {                parent.requestMore(n);            }        });        if (!child.isUnsubscribed()) {            source.unsafeSubscribe(parent);        }    }
这里delayErrorMode == IMMEDIATE,走if分支,创建一个SerializedSubscriber

然后以前面创建的SerializedSubscriber另加mapper, prefetch, delayErrorMode创建ConcatMapSubscriber

        public ConcatMapSubscriber(Subscriber<? super R> actual,                Func1<? super T, ? extends Observable<? extends R>> mapper, int prefetch, int delayErrorMode) {            this.actual = actual;            this.mapper = mapper;            this.delayErrorMode = delayErrorMode;            this.arbiter = new ProducerArbiter();            this.wip = new AtomicInteger();            this.error = new AtomicReference<Throwable>();            Queue<Object> q;            if (UnsafeAccess.isUnsafeAvailable()) {                q = new SpscArrayQueue<Object>(prefetch);            } else {                q = new SpscAtomicArrayQueue<Object>(prefetch);            }            this.queue = q;            this.inner = new SerialSubscription();            this.request(prefetch);        }
这里会创建一个ProducerArbiter,调用request,这里prefetch是2

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,调用addToRequested

    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设置为了2

回到前面的call函数

然后调用child 的setProducer,最终会调用到这里Producer的request方法

从而调用

 parent.requestMore(n);
这里的parent就是我们刚刚创建的ConcatMapSubscriber,我们看下它的requestMore方法

        void requestMore(long n) {            if (n > 0) {                arbiter.request(n);            } else            if (n < 0) {                throw new IllegalArgumentException("n >= 0 required but it was " + n);            }        }
arbiter就是前面创建的ProducerArbiter

 public void request(long n) {        if (n < 0) {            throw new IllegalArgumentException("n >= 0 required");        }        if (n == 0) {            return;        }        synchronized (this) {            if (emitting) {                missedRequested += n;                return;            }            emitting = true;        }        boolean skipFinal = false;        try {            long r = requested;            long u = r + n;            if (u < 0) {                u = Long.MAX_VALUE;            }            requested = u;            Producer p = currentProducer;            if (p != null) {                p.request(n);            }            emitLoop();            skipFinal = true;        } finally {            if (!skipFinal) {                synchronized (this) {                    emitting = false;                }            }        }    }

这里n为Long.MAX_VALUE

emitting设置为true,currentProducer为null,调用emitLoop

public void emitLoop() {        for (;;) {            long localRequested;            long localProduced;            Producer localProducer;            synchronized (this) {                localRequested = missedRequested;                localProduced = missedProduced;                localProducer = missedProducer;                if (localRequested == 0L                        && localProduced == 0L                        && localProducer == null) {                    emitting = false;                    return;                }                missedRequested = 0L;                missedProduced = 0L;                missedProducer = null;            }            long r = requested;            if (r != Long.MAX_VALUE) {                long u = r + localRequested;                if (u < 0 || u == Long.MAX_VALUE) {                    r = Long.MAX_VALUE;                    requested = r;                } else {                    long v = u - localProduced;                    if (v < 0) {                        throw new IllegalStateException("more produced than requested");                    }                    r = v;                    requested = v;                }            }            if (localProducer != null) {                if (localProducer == NULL_PRODUCER) {                    currentProducer = null;                } else {                    currentProducer = localProducer;                    localProducer.request(r);                }            } else {                Producer p = currentProducer;                if (p != null && localRequested != 0L) {                    p.request(localRequested);                }            }        }    }
满足
if (localRequested == 0L                        && localProduced == 0L                        && localProducer == null)
把emitting设置为false返回

再次回到call函数,调用

 source.unsafeSubscribe(parent);
调用source的call函数,这里的source是OnSubscribeFromIterable

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));            }        }    }
先获取值,然后调用setProducer,这里new了一个IterableProducer,最终会调用它的request方法,这里的o是ConcatMapSubscriber

       @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);            }        }
这里n为2,前面初始化ConcatMapSubscriber的时候设置的

所以这里走的是slowPath

void slowPath(long n) {            // backpressure is requested            final Subscriber<? super T> o = this.o;            final Iterator<? extends T> it = this.it;            long r = n;            long e = 0;            for (;;) {                while (e != r) {                    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;                    }                    e++;                }                r = get();                if (e == r) {                    r = BackpressureUtils.produced(this, e);                    if (r == 0L) {                        break;                    }                    e = 0L;                }            }        }
之类调用o的onNext,o是ConcatMapSubscriber

        @Override        public void onNext(T t) {            if (!queue.offer(NotificationLite.next(t))) {                unsubscribe();                onError(new MissingBackpressureException());            } else {                drain();            }        }
queue.offer会把当前值入队列调用drain

void drain() {            if (wip.getAndIncrement() != 0) {                return;            }            final int delayErrorMode = this.delayErrorMode;            for (;;) {                if (actual.isUnsubscribed()) {                    return;                }                if (!active) {                    if (delayErrorMode == BOUNDARY) {                        if (error.get() != null) {                            Throwable ex = ExceptionsUtils.terminate(error);                            if (!ExceptionsUtils.isTerminated(ex)) {                                actual.onError(ex);                            }                            return;                        }                    }                    boolean mainDone = done;                    Object v = queue.poll();                    boolean empty = v == null;                    if (mainDone && empty) {                        Throwable ex = ExceptionsUtils.terminate(error);                        if (ex == null) {                            actual.onCompleted();                        } else                        if (!ExceptionsUtils.isTerminated(ex)) {                            actual.onError(ex);                        }                        return;                    }                    if (!empty) {                        Observable<? extends R> source;                        try {                            source = mapper.call(NotificationLite.<T>getValue(v));                        } catch (Throwable mapperError) {                            Exceptions.throwIfFatal(mapperError);                            drainError(mapperError);                            return;                        }                        if (source == null) {                            drainError(new NullPointerException("The source returned by the mapper was null"));                            return;                        }                        if (source != Observable.empty()) {                            if (source instanceof ScalarSynchronousObservable) {                                ScalarSynchronousObservable<? extends R> scalarSource = (ScalarSynchronousObservable<? extends R>) source;                                active = true;                                arbiter.setProducer(new ConcatMapInnerScalarProducer<T, R>(scalarSource.get(), this));                            } else {                                ConcatMapInnerSubscriber<T, R> innerSubscriber = new ConcatMapInnerSubscriber<T, R>(this);                                inner.set(innerSubscriber);                                if (!innerSubscriber.isUnsubscribed()) {                                    active = true;                                    source.unsafeSubscribe(innerSubscriber);                                } else {                                    return;                                }                            }                            request(1);                        } else {                            request(1);                            continue;                        }                    }                }                if (wip.decrementAndGet() == 0) {                    break;                }            }        }
active开始为false,进入后会把它设置为true,这里如果active为true,则表示前一个操作未完成,直接返回(前一个操作什么时候完成后面会讲)
出队列,主要的是调用mapper的call函数

public Observable<Integer> call(Integer number) {                return Observable.just(number * number).subscribeOn(Schedulers.from(JobExecutor.getInstance()));            }
最终会创建一个ScalarAsyncOnSubscribe它的onSubscribe是OperatorSubscribeOn  

回到drain函数,source不是ScalarSynchronousObservable,走else分支

 ConcatMapInnerSubscriber<T, R> innerSubscriber = new ConcatMapInnerSubscriber<T, R>(this);                                inner.set(innerSubscriber);                                if (!innerSubscriber.isUnsubscribed()) {                                    active = true;                                    source.unsafeSubscribe(innerSubscriber);                                } else {                                    return;                                }                            }                            request(1);

创建一个ConcatMapInnerSubscriber并设置给inner,inner是我们初始化时创建的SerialSubscription

并走if分支,active设置为true,调用unsafeSubscribe,最终调用ScalarAsyncOnSubscribe的call函数

 public void call(Subscriber<? super T> s) {            s.setProducer(new ScalarAsyncProducer<T>(s, value, onSchedule));        }

这里创建了一个ScalarAsyncProducer,调用setProducer

        @Override        public void setProducer(Producer p) {            parent.arbiter.setProducer(p);        }

这里的arbiter是ProducerArbiter,

public void setProducer(Producer newProducer) {        synchronized (this) {            if (emitting) {                missedProducer = newProducer == null ? NULL_PRODUCER : newProducer;                return;            }            emitting = true;        }        boolean skipFinal = false;        try {            currentProducer = newProducer;            if (newProducer != null) {                newProducer.request(requested);            }            emitLoop();            skipFinal = true;        } finally {            if (!skipFinal) {                synchronized (this) {                    emitting = false;                }            }        }    }

主要调用

 newProducer.request(requested);
newProducer为ScalarAsyncProducer
        @Override        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

      w.schedule(new Action0() {                        @Override                        public void call() {                            try {                                a.call();                            } finally {                                w.unsubscribe();                            }                        }                    });

------------------------------------------------------------------------------------------------------------

这里的a是ScalarSynchronousObservable,这里已经在另外一个线程执行了

我们看一下他的call

 @Override        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是ConcatMapInnerSubscriber,他的onNext函数我们就不去分析了,我们看一下他的onComplete函数

 public void onCompleted() {            parent.innerCompleted(produced);        }
这里parent为ConcatMapSubscriber

     void innerCompleted(long produced) {            if (produced != 0L) {                arbiter.produced(produced);            }            active = false;            drain();        }

这里会把active 设置为false重新调用drain函数,如果队列中有值,则继续执行队列中的请求
----------------------------------------------------------------------------------

我们重新回到前面第一个线程在schedule启动一个线程之后,继续回到slowPath,然后处理下一个请求,把值入队列,如果当前有请求执行,则返回。这样所有的执行都是一个接着一个执行的。

所以最终的输出结果也是顺序的

4, 9, 16, 25, 36, 49, 64, 81, 100, 
这里在调试的时候为了 延迟一个操作执行的时间,模拟一个操作长时间执行,drain中active 为false状态,我们可以在sursurib中添加sleep

      ArrayList aa = new ArrayList<>(Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10));        Observable.from(aa).concatMap(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 + ", ");                try {                    Thread.sleep(60000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        });












0 0