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

则不会有问题




0 0
原创粉丝点击