订阅后线程仍然存在

时间:2018-09-17 13:57:36

标签: reactive-programming rx-java2 project-reactor

我们当前正在从RxJava2迁移到Project Reactor。为了使工作并行化,我们通过Schedulers.newThread()为每个并行HTTP请求创建一个新线程。我们无法重用线程,因为Spring的SecurityContext已绑定到ThreadLocal

最近,我们遇到了一个错误,那就是在一段时间后JVM遇到了OutOfMemory异常,因为未处理创建的线程导致了数千个驻留线程,而RxJava则是在成功的HTTP请求之后我们丢弃的线程。

对于RxJava,代码如下,在最后一行中有断点时,没有显示活动的附加线程。

Observable<String> deferred = Observable.fromCallable(() -> "1")
            .subscribeOn(io.reactivex.schedulers.Schedulers.newThread());
Observable<String> deferred2 = Observable.fromCallable(() -> "2")
            .subscribeOn(io.reactivex.schedulers.Schedulers.newThread());
System.out.println("obs: " + deferred.blockingSingle());
System.out.println("obs2: " + deferred2.blockingSingle());

但是对于Project Reactor,在两个标准输出之后,两个线程仍然处于活动状态。

Mono<String> mono1 = Mono.fromSupplier(() -> "1").subscribeOn(Schedulers.newSingle("single"));
Mono<String> mono2 = Mono.fromSupplier(() -> "1").subscribeOn(Schedulers.newSingle("single"));
System.out.println("Mono1: " + mono1.block());
System.out.println("Mono2: " + mono2.block());

为此,一种解决方案是在onFinally中手动拆除调度程序:

 Scheduler newSingle = Schedulers.newSingle("single");
 Mono<String> doFinally = Mono.defer(() -> Mono.fromSupplier(() -> "1")).subscribeOn(newSingle).doFinally(s -> {
        newSingle.dispose();
 });

但是,这真的必要吗,还是有办法建立与RxJava2中相同的行为?

0 个答案:

没有答案