我与observeOn()
和subscribeOn()
使用RxJava进行双重拍摄。我知道他们没有在单个流上并行排放。换句话说,单一的排放流只能放在一个线程上吗?我的测试似乎表明了这一点。我的理解是,您必须flatMap()
调度程序(如.flatMap(v -> Observable.just(v).subscribeOn(Schedulers.computation()))
中所述)在单个流上并行化排放。
如果是这种情况,那么调度程序会发生线程饥饿吗?如果我的计算调度程序有5个线程,但我有超过5个长时间运行的异步流正在处理,是否有可能发生饥饿?或者仅仅因为RxJava的性质,这不太可能吗?
public class Test {
public static void main(String[] args) {
Observable<String> airports = Observable.just("ABQ", "HOU",
"PHX", "DAL", "DFW", "AUS","SAN","LAX","JFK");
airports.subscribeOn(Schedulers.io()).map(Test::stall)
.subscribe(s -> System.out.println("Sub1 " + s +
" " + Thread.currentThread().getName()));
airports.subscribeOn(Schedulers.io()).map(Test::stall)
.subscribe(s -> System.out.println("Sub2 " + s +
" " + Thread.currentThread().getName()));
sleep();
}
private static String stall(String str) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return str;
}
private static void sleep() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
使用flatMap
,一个异步源可能会被其他人淹没,并且无法在自己的源上取得进展。然而,在实践中,我还没有看到这种情况发生,因为操作系统和JVM打嗝提供了足够的喘息空间以及flatMap
本身的背压和仲裁。如果您担心这种压倒性的问题,可以将maxConcurrent
参数与flatMap
重载一起使用,并限制并发订阅的数量。
RxJava主要以非阻塞方式编写,因此当需要合并或组合源时,它们并不真正等待彼此。
计算调度程序是一个单线程执行程序池,以循环方式分配给调用者。我不了解标准执行者的公平性。