Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
RxJava中值发送代码和值接收代码的线程执行_Java_Rx Java3 - Fatal编程技术网

RxJava中值发送代码和值接收代码的线程执行

RxJava中值发送代码和值接收代码的线程执行,java,rx-java3,Java,Rx Java3,我有以下代码: private static void log(Object msg) { System.out.println( Thread.currentThread().getName() + ": " + msg); } Observable<Integer> naturalNumbers = Observable.create(emitter ->

我有以下代码:

private static void log(Object msg) {
        System.out.println(
                Thread.currentThread().getName() +
                        ": " + msg);
}

Observable<Integer> naturalNumbers = Observable.create(emitter -> {
            log("Invoked"); // on main thread
            Runnable r = () -> {
                log("Invoked on another thread");
                int i = 0;
                while(!emitter.isDisposed()) {
                    log("Emitting "+ i);
                    emitter.onNext(i);
                    i += 1;
                }
            };
            new Thread(r).start();
        });
Disposable disposable = naturalNumbers.subscribe(i -> log("Received "+i));

为什么会这样?RxJava默认情况下是否在同一线程上运行代码发送值(可观察)和代码接收值(观察者)?

让我们看看,如果使用
线程执行可运行的:

试验 输出 似乎主入口点是从
main
thread调用的,新创建的
thread
被称为
thread-0

为什么会这样?RxJava默认情况下是否在同一线程上运行代码发送值(可观察)和代码接收值(观察者)

默认情况下,
RxJava
是单线程的。因此,如果未通过
observeOn
subscribeOn
或不同的线程布局对生产者进行不同的定义,生产者将在
消费者
(subscriber)-线程上发出值。这是因为默认情况下,
RxJava
运行订阅堆栈上的所有内容

例2 在您的示例中,很明显,main方法是从主线程调用的。此外,
subscribebeactual
调用也在调用线程(
main
)上运行。但是
Observable#create
lambda从新创建的线程
thread-0
调用
onNext
。该值从调用线程推送到订阅者。在这种情况下,调用线程是
thread-0
,因为它调用下游订阅服务器上的
onNext

如何区分生产者和消费者? 使用
observeOn
/
subscribeOn
操作符处理
RxJava
中的并发

我应该使用低级线程构造吗ẁ是RxJava吗? 不,您不应该使用
新线程
来分离生产者和消费者。很容易破坏契约,即不能同时调用(
onNext
),从而破坏契约。这就是为什么
RxJava
使用
Worker
s提供了一个名为
Scheduler
的构造,以减少此类错误

注:
我认为这篇文章描述得很好:。请注意,这是Rx.NET,但原理完全相同。如果您想阅读有关使用
RxJava的并发性的内容,您还可以查看Davids Blog()或阅读本书(使用RxJava进行反应式编程)

是的,默认情况下RxJava是同步的。您需要使用诸如
observeOn
之类的运算符来更改事件观察发生的位置。这样的操作符增加了开销,许多操作一开始就不需要更改线程。对于其余部分,“目标”线程必须以
调度程序的形式指定。在编程社区中,“同步”这个词确实是超负荷的,我看到了人们定义它的几种方式。我猜你在这里的意思是,数据的释放和数据的消耗都发生在同一个线程中。如果是这样,我有一个问题。如果您在输出中看到,则存在发射代码和接收器代码的交错。如果两者都在同一个线程上,这怎么可能呢?为什么它们会在不同的线程上?在相同的线程上下文中调用它们的
log
方法。这些是常规的Java方法调用,它们具有顺序,并且一个接一个地发生。
Thread-0: Invoked on another thread
Thread-0: Emitting 0
Thread-0: Received 0
Thread-0: Emitting 1
Thread-0: Received 1
Thread-0: Emitting 2
Thread-0: Received 2
@Test
  void threadTest() throws Exception {
    log("main");
    CountDownLatch countDownLatch = new CountDownLatch(1);

    new Thread(
            () -> {
              log("thread");
              countDownLatch.countDown();
            })
        .start();

    countDownLatch.await();
  }
main: main
Thread-0: thread
@Test
  void fdskfkjsj() throws Exception {
      log("main");

      Observable<Integer> naturalNumbers =
        Observable.create(
            emitter -> {
              log("Invoked"); // on main thread
              Runnable r =
                  () -> {
                    log("Invoked on another thread");
                    int i = 0;
                    while (!emitter.isDisposed()) {
                      log("Emitting " + i);
                      emitter.onNext(i);
                      i += 1;
                    }
                  };
              new Thread(r).start();
            });
    Disposable disposable = naturalNumbers.subscribe(i -> log("Received " + i));

    Thread.sleep(100);
  }
main: main
main: Invoked
Thread-0: Invoked on another thread
Thread-0: Emitting 0
Thread-0: Received 0
Thread-0: Emitting 1