可见未在其他线程上运行

时间:2019-01-01 19:29:28

标签: java asynchronous rx-java

我正在用RxJava做一些试验。这是我的代码:

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
  }

这是上面代码的输出:

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]

我的问题是,如果737在线程RxNewThreadScheduler-1上运行并且该线程睡眠20秒,那么747线程应该继续执行,对吗?但是在输出中,我们可以看到与747对应的“ 3”输出晚于737的输出。此外,该运算符在与737相同的线程上被调用。

更准确地说,为什么仅在737线程唤醒后才运行747的“ 3”? 747正在尝试使用与737相同的线程。按照我的理解,流程应该是:

  1. 可观察到的737在线程A上发出,该线程立即休眠20秒。
  2. 747在线程B上发出,并继续执行。
  3. 与747相对应的操作应该在其他线程上更早完成。

有人可以向我解释这种行为吗?

0 个答案:

没有答案