Schedulers.io()是同步还是异步运行作业?

时间:2019-07-26 14:28:39

标签: rx-java

根据官方文档站点https://github.com/ReactiveX/RxJava/wiki/Connectable-Observable-Operators上的小样本,ConnectableObservable应该同时运行与每个可观察对象关联的操作,但是我正在研究https://www.androidhive.info/RxJava/flatmap-concatmap-operators-flight-tickets-app/中的以下示例代码似乎与每个观察者相关的工作都是按顺序运行的,即使他使用的是ConnectableObservable。我认为这与Schedulers.io()有关,但此调度程序由无限制的线程池支持,因此,从理论上讲,它有多个可用的单个线程来处理两个工作负载,除非我遗漏了一些东西(我肯定是)。 Schedulers.io()是同步还是异步运行作业?或者换一种说法,为什么与两个观察员相关的工作都按顺序进行?为什么第二个观察者可以安全地假设与第一个观察者相关的工作是在它开始处理自己的工作负载之前完成的?

    ConnectableObservable<List<Ticket>> ticketsObservable = getTickets(from, to).replay();

    /**
     * Fetching all tickets first
     * Observable emits List<Ticket> at once
     * All the items will be added to RecyclerView
     * */
    disposable.add(
            ticketsObservable
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(new DisposableObserver<List<Ticket>>() {

                        @Override
                        public void onNext(List<Ticket> tickets) {
                            // Refreshing list
                            ticketsList.clear();
                            ticketsList.addAll(tickets);
                            mAdapter.notifyDataSetChanged();
                        }

                        @Override
                        public void onError(Throwable e) {
                            showError(e);
                        }

                        @Override
                        public void onComplete() {

                        }
                    }));

    /**
     * Fetching individual ticket price
     * First FlatMap converts single List<Ticket> to multiple emissions
     * Second FlatMap makes HTTP call on each Ticket emission
     * */
    disposable.add(
            ticketsObservable
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    /**
                     * Converting List<Ticket> emission to single Ticket emissions
                     * */
                    .flatMap(new Function<List<Ticket>, ObservableSource<Ticket>>() {
                        @Override
                        public ObservableSource<Ticket> apply(List<Ticket> tickets) throws Exception {
                            return Observable.fromIterable(tickets);
                        }
                    })
                    /**
                     * Fetching price on each Ticket emission
                     * */
                    .flatMap(new Function<Ticket, ObservableSource<Ticket>>() {
                        @Override
                        public ObservableSource<Ticket> apply(Ticket ticket) throws Exception {
                            return getPriceObservable(ticket);
                        }
                    })
                    .subscribeWith(new DisposableObserver<Ticket>() {

                        @Override
                        public void onNext(Ticket ticket) {
                            int position = ticketsList.indexOf(ticket);

                            if (position == -1) {
                                // TODO - take action
                                // Ticket not found in the list
                                // This shouldn't happen
                                return;
                            }

                            ticketsList.set(position, ticket);
                            mAdapter.notifyItemChanged(position);
                        }

                        @Override
                        public void onError(Throwable e) {
                            showError(e);
                        }

                        @Override
                        public void onComplete() {

                        }
                    }));

    // Calling connect to start emission
    ticketsObservable.connect();

1 个答案:

答案 0 :(得分:1)

Scheduler允许工作在执行上下文中运行; Scheduler.io(), the context is a pool of threads. The observeOn()操作符的作用是告诉观察者链在该上下文中运行。

但是,实际上它的工作方式是只有一个线程在运行观察者链,因为这就是您要使用的全部。因为observerOn()仅被调用一次,所以在实例化观察者链时,只有一个线程可用。如果您多次实例化观察者,则每次都会从池中选择一个线程并将该线程用于特定实例。

RxJava不是多线程的

关于观察者链的运作有一些规则;其中,一次只能有一个线程可以将值发送到链中。通常,任何观察者链都完全由单个线程执行,因此默认情况下满足约束条件。

RxJava控制哪些线程处于活动状态

使用subscribeOn()observeOn()和其他隐式或显式选择调度程序的运算符,您可以控制何时以及如何在线程之间划分工作。将这些运算符放在链中的位置很重要。

例如,如果将observeOn(Schedulers.io())运算符放在第一个flatMap()运算符之后 ,那么您将得到不同的结果。 flatMap()为每个输入启动一个新的观察者链;每个观察者链可能都有自己的线程。