package hu.akarnokd.rxjava2;

import java.util.*;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Scheduler;
import io.reactivex.schedulers.Schedulers;
import ix.Ix;

public class WhichThread {

    public static void main(String[] args) throws Exception {
        
        List<Observable<Integer>> sources = new ArrayList<>();
        sources.add(Observable.just(1).delay(1, TimeUnit.MINUTES));
        sources.add(Observable.<Integer>empty());
        sources.add(Observable.<Integer>empty().delay(1, TimeUnit.MINUTES));
        sources.add(Observable.just(1));
        
        for (Observable<Integer> source : sources) {
            List<List<String>> names = new ArrayList<>();
            names.add(new ArrayList<>());
            names.add(new ArrayList<>());
            names.add(new ArrayList<>());
            names.add(new ArrayList<>());
            
            Scheduler main = Schedulers.single();
            int n = 1000;
            
            for (int i = 0; i < n; i++) {
                main.scheduleDirect(() -> {
                    source
                    .doOnSubscribe(s -> names.get(0).add(Thread.currentThread().getName()))
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .doFinally(() -> names.get(1).add(Thread.currentThread().getName()))
                    .doOnSubscribe(s -> names.get(2).add(Thread.currentThread().getName()))
                    .subscribeOn(main)
                    .unsubscribeOn(main)
                    .observeOn(main)
                    .doFinally(() -> names.get(3).add(Thread.currentThread().getName()))
                    .subscribe()
                    .dispose();
                });
                
                Thread.sleep(100);
                
                if (i % 10 == 0) {
                    System.out.println(i);
                    for (int j = 0; j < 4; j++) {
                        System.out.print(j);
                        System.out.print(" -> ");
                        Ix.from(names.get(j)).groupBy(v -> {
                            if (v.contains("Single")) {
                                return "main";
                            }
                            return "io";
                        })
                        .flatMap(v -> v.count().map(c -> v.key() + ": " + c))
                        .join()
                        .foreach(System.out::println);
                    }
                }
            }
        }
    }
}

@@ -2535,32 +2535,557 @@
 %7D%0A            %7D%0A
+            System.out.println(n);%0A            for (int j = 0; j %3C 4; j++) %7B%0A                System.out.print(j);%0A                System.out.print(%22 -%3E %22);%0A                Ix.from(names.get(j)).groupBy(v -%3E %7B%0A                    if (v.contains(%22Single%22)) %7B%0A                        return %22main%22;%0A                    %7D%0A                    return %22io%22;%0A                %7D)%0A                .flatMap(v -%3E v.count().map(c -%3E v.key() + %22: %22 + c))%0A                .join()%0A                .foreach(System.out::println);%0A            %7D%0A
         %7D%0A    %7D%0A

Print final result