Search code examples
javaasynchronousrx-javarx-java2

Can Schedulers.io() be used to make asynchronous DB calls?


Can Schedulers.io() be used to make asynchronous DB calls? Will it block my main thread?


Solution

  • Yes, it can be used, and no, it won't block your main thread. Its aim is exactly that, performing blocking IO aynchronously, such as a DB call.

    The only scenario in which io blocks the main thread would be all the threads of the pool being occupied; That shouldn't happen with the default Scheduler, but if you want to control how many threads are launched at max, you could set your custom Scheduler with a limited size in order to avoid thread party in your ram:

    Scheduler scheduler = Schedulers.from(Executors.newFixedThreadPool(3));
    

    Judge which approach is best for you. The first one makes thing simpler and should never block the main thread. The contra is the attack of the clones from the default Scheduler. The second one, if well configured, would be the optimal option.

    And some way to use it:

    Observable.just("yourDbTable")
             .flatMap(t->{ Record rec = selectFrom(t); .... })
             .subscribeOn(Schedulers.io()); 
    

    Schedulers.io()

    Creates and returns a Scheduler intended for IO-bound work. The implementation is backed by an Executor thread-pool that will grow as needed. This can be used for asynchronously performing blocking IO.

    The implementation is backed by a pool of single-threaded ScheduledExecutorService instances that will try to reuse previously started instances used by the worker returned by Scheduler.createWorker() but otherwise will start a new backing ScheduledExecutorService instance.

    Note that this scheduler may create an unbounded number of worker threads that can result in system slowdowns or OutOfMemoryError. Therefore, for casual uses or when implementing an operator, the Worker instances must be disposed via Disposable.dispose().

    Docs also suggest to avoid computational work on it.