如何让Rx请求在单独的线程中更快划分?

时间:2017-07-05 09:29:27

标签: android rx-java2

对于每个数据对象,我正在获取更多详细信息,因此需要很长时间才能拥有我存储在DB中的所有数据, 我的问题如何更快地组织map(data->apiIcaSeResource.fetchDataDetail),比如划分不同的线程

    apiIcaSeResource
    .fetchData("")
    .map(Datas::datas)
    .toFlowable()
    .flatMapIterable(datas->datas)
    .map(data - >apiIcaSeResource.fetchDataDetail)
    .map(dataDetail->Pair.create(dataDetail,data))
    .toList()
    .map(store::insert())
.subscribeOn(Schedulers.io())

3 个答案:

答案 0 :(得分:0)

您可以使用ThreadPoolExecutor轻松管理多个线程和工作分配。 ThreadPoolExecutor根据需要管理线程创建和终止。

乍一看它看起来非常令人生畏,但是当你花10分钟阅读它时它真的很简单。

自定义池构造函数如下所示:

document

然后:

Executor executor = new ThreadPoolExecutor(
     int corePoolSize,
     int maximumPoolSize,
     long keepAliveTime, TimeUnit unit,
     BlockingQueue<Runnable> workQueue,
     ThreadFactory threadFactory,
     RejectedExecutionHandler handler
);

您也可以使用内置执行程序。

您可以在此处详细了解:ThreadPoolExecutor on the Android developers site

答案 1 :(得分:0)

只需在新主题中执行每个fetchDataDetail即可。您需要更改map

flatMap
apiIcaSeResource
    .fetchData("")
    .map(Datas::datas)
    .toFlowable()
    .flatMapIterable(datas->datas)
    .flatMap(data - >apiIcaSeResource.fetchDataDetail()
                     .subscribeOn(Schedulers.io())     // Perform each operation in a separate thread
    .map(dataDetail->Pair.create(dataDetail,data))
    .toList()
    .map(store::insert())
    .subscribeOn(Schedulers.io())

答案 2 :(得分:0)

您需要做的是使用flatMap并应用于每个Observable由具有固定大小的Executor线程池支持的调度程序。更确切地说,您必须使用computation()调度程序。

apiIcaSeResource
    .fetchData("")
    .map(Datas::datas)
    .flatMapIterable(datas->datas)
    .flatMap(data -> apiIcaSeResource.fetchDataDetail()
                     .subscribeOn(Schedulers.computation())
                     .map(dataDetail -> Pair.create(dataDetail,data)))

    .toList()
    .map(store::insert())

如果你不这样做,并且你使用例如Schedulers.io(),你将同时创建大量的线程,并且你会遇到严重的性能问题。特别是对于您的情况,您需要执行大量请求。

Schedulers.computation()的问题在于,正如文档所说,

  建议使用Schedulers.computation()来对此进行阻塞,IO绑定工作   调度器。

所以将它用于网络呼叫似乎不太好。

因此,另一种选择是使用Schedulers.io()Schedulers.newThread()指定Observable的活动线程限制。例如,假设您希望最多有4个正在运行的网络呼叫,则可以执行以下操作:

final static int MAX_ACTIVE_THREADS = 4;

apiIcaSeResource
    .fetchData("")
    .map(Datas::datas)
    .flatMapIterable(datas->datas)
    .flatMap(data -> apiIcaSeResource.fetchDataDetail()
                     .map(dataDetail -> Pair.create(dataDetail,data))
                     .subscribeOn(Schedulers.io()), MAX_ACTIVE_THREADS)
    .toList()
    .map(store::insert())

您可能可以做的另一项性能改进是使用例如buffer()运算符批量从第二个服务检索的数据。这样,您将在时间插入多行。请注意,我不认为这是流量的瓶颈,因为网络操作确实较慢,但在我看来它仍然是一个很好的改进。