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