Retrofit结合Rxjava使用时,Schedulers.newThread()和Schedulers.io()的区别是什么?

85

在Retrofit网络请求中,使用 Schedulers.newThread()Schedulers.io() 有什么好处?我看到很多示例使用 io(),但我想了解原因。

示例情况:

observable.onErrorResumeNext(refreshTokenAndRetry(observable))
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())...

对抗

observable.onErrorResumeNext(refreshTokenAndRetry(observable))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())...

我看到的其中一个原因是 -

newThread()为每个工作单元创建一个新线程。io()将使用线程池。

但这个参数对应用程序有什么影响?还有哪些方面需要考虑?

1个回答

103

您说得对,使用 Schedulers.io() 的好处在于它使用线程池,而 Schedulers.newThread() 则不使用。

您应该考虑使用线程池的主要原因是它们维护了一些预先创建的空闲线程,等待工作。这意味着当您有工作要做时,您不需要经过创建线程的开销。一旦您的工作完成,该线程也可以被重复使用于将来的工作,而不是不断地创建和销毁线程。

创建线程可能很昂贵,因此尽量减少动态创建线程的数量通常是好的。

关于线程池的更多信息,我推荐:


5
考虑到一些使用情况可能不适合无界线程池,因此可能值得添加一个关于Scheduler.io()的评论。请参见https://dev59.com/D10Z5IYBdhLWcg3wlRQV。 - Dave Moten
@DaveMoten 有哪些使用情况不适合使用 Schedulers.io 的线程池? - IgorGanapolsky
4
如果使用Schedulers.io()同时需要处理大量工作,可能会遇到操作系统的I/O限制(例如最大打开文件数、最大TCP连接数,这些连接可能会在被处理后一段时间内仍保持打开状态以确保可靠性)。每个新线程也需要一定数量的RAM(大于512K但约为1M),因此可能会耗尽RAM。 - Dave Moten
这些线程共享同一内存吗?例如,在一个 I/O 线程中创建的对象是否可以在另一个 I/O 线程中访问。 - Eido95
2
@Eido95 他们共享同一个堆,而不是同一个栈。就变量而言,是的,你可以在线程之间共享变量(但要注意确保这些变量是线程安全的)。 - Bryan Herbst
我在两周前看到了你的回复,并使用 Schedulers.io() 来实现所有我的 Observables。一切都正常,但是应用程序运行速度过慢。当我将所有的 Schedulers.io() 替换为 Schedulders.newThread() 后,我的应用程序运行速度提高了五倍。我强烈建议在网络连接中使用新线程。 - Mehdi Pourfar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接