Under what situation does it need to use blockingSubscribe in RxJava ?
Like consider the following, it can print the result.
Observable.just(1, 2, 3, 4, 5)
.subscribe(line -> System.out.println(line));
While if change to the following, it does not print the result, but why so ?
Observable.interval(500, TimeUnit.MILLISECONDS)
.subscribe(line -> System.out.println(line));
And if change to use blockingSubscribe, it can show the result again.
Observable.interval(500, TimeUnit.MILLISECONDS)
.blockingSubscribe(line -> System.out.println(line));
I read that by "blockingSubscribe" it is to block the main thread, but why would one block the main thread (like in real world situation), what if doesn't want to block the main thread execution but still want to use Observable.interval ?
The first example runs on the stack of the subscribing thread. When you subscribe a subscribeAcutal will happen from the calling thread. The just operator will then onNext all items (1,2,3,4,5) synchronously to the subscriber. On each onNext the Subscribe will be called and the number will be printed.
Observable.just(1, 2, 3, 4, 5)
.subscribe(line -> System.out.println(line));
The second example will not print anything, because concurrency is involved and your main method "falls through". Under the hood the Interval-Operator uses a scheduler. On subscription the Interval operator will add a job to the Scheduler, which will run in 500 ms. The calling thread calls subscribe actual, the operator addd the job to a scheduler and is done. There are no more stackframes on the stack to pop. Therefore the subscribe-Method invocation is finished and the calling (main) thread is able to proceed. In your case the there are no more methods to call and therefore the programm exits. The programm will exit faster than the emit, which will happen in 500ms. This is the reason, why you do not see any output on System.out.
Observable.interval(500, TimeUnit.MILLISECONDS)
.subscribe(line -> System.out.println(line));
If you want to stop your main-thread from exiting before the singla has been printed, you could just add a
Thread.sleep(1_000)
The main-thread will stop at Thread#sleep for 1000ms. While the main-thread is blocked, the scheduler will emit a value on another thread, which will then invoke the onNext of the subscriber. The println call will be invoked and the value will be printed.
What you are trying to achieve here is to sync. the main thread with another one. This is there blocking*-Subscription come into play. If you want to join one Thread with another one, you have to block the thread until a specific signal has arrived.
what if doesn't want to block the main thread execution but still want to use Observable.interval
The main thread of execution in your application is not allowed to finish.
Just create/ start a non-daemon thread (e.g. Android, SWT, JavaFX)^1