85

What are the benefits to use Schedulers.newThread() vs Schedulers.io() in Retrofit network request. I have seen many examples that use io(), but I want to understand why.

Example situation:

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

vs

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

One of the reasons i have seen is -

newThread() creates a new thread for each unit of work. io() will use a thread pool

But what is the influence of that argument on the app? And what other aspects there are?

Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
Mikelis Kaneps
  • 4,576
  • 2
  • 34
  • 48

1 Answers1

103

You are correct that the benefit of using Schedulers.io() lies in the fact that it uses a thread pool, whereas Schedulers.newThread() does not.

The primary reason that you should consider using thread pools is that they maintain a number of pre-created threads that are idle and waiting for work. This means that when you have work to be done, you don't need to go through the overhead of creating a thread. Once your work is done, that thread can also be re-used for future work instead of constantly creating and destroying threads.

Threads can be expensive to create, so minimizing the number of threads that you are creating on the fly is generally good.

For more information on thread pools, I recommend:

Community
  • 1
  • 1
Bryan Herbst
  • 66,602
  • 10
  • 133
  • 120
  • 5
    Might be worth adding a comment about Scheduler.io() being based on an unbounded thread pool which might not be appropriate for some use cases. See http://stackoverflow.com/questions/31276164/rxjava-schedulers-use-cases – Dave Moten Oct 30 '15 at 01:43
  • @DaveMoten What use cases are inappropriate for thread pool via `Schedulers.io`? – IgorGanapolsky Jan 19 '16 at 16:35
  • 4
    If you have a lot of concurrent work to do with `Schedulers.io()` then you could bump into OS i/o limits (for example max number of open files, max number of tcp connections which for reliability purposes may stay open for a period even after being disposed). Each new thread also requires a minimum non-trivial amount of RAM (> 512K but work on 1M) so you could run out of RAM. – Dave Moten Jan 19 '16 at 22:57
  • Does those threads share the same memory? e.g. object created in one io thread and being accessed in another io thread. – Eido95 Nov 21 '16 at 14:56
  • 2
    @Eido95 they share the same heap, not the same stack. As far as variables go, yes you can share variables between threads (with all the typical warnings about making sure those variables are thread-safe). – Bryan Herbst Nov 21 '16 at 15:28
  • I have read your response about two weeks ago and implemented all my Observables with Schedulers.io(). Everything worked fine, but app was too slow. After replacing all Schedulers.io() with Schedulders.newThread(), my apps runs five times faster. I highly recommend using new thread for network connections. – Mehdi Pourfar Apr 04 '17 at 00:55