I am experimenting a bit with RxJava. Here's my code:
public static void main(String[] args) throws InterruptedException {
List<String> l = new ArrayList<>();
l.add("737");
l.add("747");
Observable.from(l)
.doOnNext(
a -> {
System.out.println(
"1: "
+ a
+ ", Thread:"
+ Thread.currentThread().getName()
+ " Timestamp: "
+ System.currentTimeMillis());
})
.flatMap(
a -> {
System.out.println(
"2: "
+ a
+ ", Thread:"
+ Thread.currentThread().getName()
+ " Timestamp: "
+ System.currentTimeMillis());
return Observable.just(a).subscribeOn(Schedulers.newThread());
})
.map(
a -> {
if (a.equals("737")) {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return a;
})
.map(
a -> {
System.out.println(
"3: "
+ a
+ ", Thread: "
+ Thread.currentThread().getName()
+ " Timestamp: "
+ System.currentTimeMillis());
return a.concat(" Boeing");
})
.reduce(
new ArrayList<>(),
(a, b) -> {
System.out.println(
"4: "
+ b
+ ", Thread: "
+ Thread.currentThread().getName()
+ " Timestamp: "
+ System.currentTimeMillis());
a.add(b);
return a;
})
.subscribe(
a -> {
System.out.println(
"4: "
+ a
+ ", Thread: "
+ Thread.currentThread().getName()
+ " Timestamp: "
+ System.currentTimeMillis());
System.out.println("Reduce result is: " + a);
});
Thread.sleep(500000); //to prevent the main thread from exiting
}
Here's an output of the above code:
1: 737, Thread:main Timestamp: 1546369697211
2: 737, Thread:main Timestamp: 1546369697211
1: 747, Thread:main Timestamp: 1546369697235
2: 747, Thread:main Timestamp: 1546369697235
3: 737, Thread: RxNewThreadScheduler-1 Timestamp: 1546369717238
4: 737 Boeing, Thread: RxNewThreadScheduler-1 Timestamp: 1546369717238
3: 747, Thread: RxNewThreadScheduler-1 Timestamp: 1546369717239
4: 747 Boeing, Thread: RxNewThreadScheduler-1 Timestamp: 1546369717239
4: [737 Boeing, 747 Boeing], Thread: RxNewThreadScheduler-1 Timestamp: 1546369717239
Reduce result is: [737 Boeing, 747 Boeing]
My question is if the 737 is running on the thread RxNewThreadScheduler-1 and this thread is sleeping for 20 seconds, the 747 thread should have continued execution, right? But in the output we can see that the output corresponding to '3' for 747 comes later than for 737. Further, this operator is getting called on the same thread as 737.
To put it more precisely, why is the '3' for 747 running only after the thread for 737 has woken up? It would appear as it 747 is trying to use the same threads as 737. As I understand this, the flow should have been:
- 737 observable is emitted on thread A, which immediately sleep for 20s.
- 747 is emitted on thread B, and it continues execution.
- Operations corresponding to 747 should have completed earlier on a different thread.
Can someone explain this behaviour to me?