.flatMap()线程卡住了

时间:2019-06-17 19:22:31

标签: java reactive-programming project-reactor

  public static void main(String[] args) {
    Flux.fromIterable(Arrays.asList("a","b","c"))
        .flatMap(a -> Mono.just(a).subscribeOn(Schedulers.parallel()))
        .doOnNext(
            a ->
                System.out.println(
                    "Receivedededed " + a + " on thread:" + Thread.currentThread().getName()))
        .flatMap(
            a -> {
              System.out.println(
                  "Received: " + a + " on threads: " + Thread.currentThread().getName());
              if ("a" == a) return getCreditScore(a);
              else return Mono.just(a);
            })
        .subscribe(a -> System.out.println("afka" + a));

    System.out.println("Main Thread Free");

    try {
      Thread.sleep(Integer.MAX_VALUE);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

我得到以下输出:

Receivedededed a on thread:parallel-1
Received: a on threads: parallel-1
Main Thread Free

然后无限等待

getCreditScore(a)的线程无限等待。

现在,据我所知,flatMap急切地订阅了所有内部流,并且在订阅另一个内部流之前不必等待它们完成。由于我使用过.subscribeOn(),因此第一个flatMap在两个不同的线程上发出事件。第二个flatMap应该订阅对应于“ b”和“ c”的事件,即使包含“ a”的线程正在等待,其余的线程是空闲的,而flatMap不等待订阅其他流之前完成。

调试器显示parallel-1处于休眠状态(这是正确的,因为getCreditScore(a)使线程无限期地休眠),parallel-2parallel-3处于等待状态。

我要去哪里错了?

1 个答案:

答案 0 :(得分:3)

这是因为每个操作员一次都处理其中的项目。这就是反应的症结所在。 在您的处理逻辑中,由于您将无限期地阻塞线程,因此其他项目(“ b”,“ c”)仅排入队列,并且从未进行处理。 当然,“ {a”首先被推入队列,因为Flux. fromIterable是按顺序执行的。

不是显式地控制线程,而是使用Mono.delay返回“ promise”。这样可以确保打印出“ b”和“ c”