Rx java 为什么rxjava2共享运营商不是多播?

Rx java 为什么rxjava2共享运营商不是多播?,rx-java,rx-java2,Rx Java,Rx Java2,当我的所有订户在进入下一个发射之前接收到相同的发射时,就会发生多播。但是当我使用share命令时,我没有看到多播。我有一个昂贵的手术,我只想做一次。让我们看看这段代码: var ob1 = Observable.fromArray(1,2,3,4,5).map { println("expensive operation") it * 2 } fun doMultiplyBy2(){ ob1.flatMap { Observable.

当我的所有订户在进入下一个发射之前接收到相同的发射时,就会发生多播。但是当我使用share命令时,我没有看到多播。我有一个昂贵的手术,我只想做一次。让我们看看这段代码:

var  ob1 = Observable.fromArray(1,2,3,4,5).map {
       println("expensive operation")
       it * 2
   }

    fun doMultiplyBy2(){
        ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}

        ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}

        ob1.share()
    }
}
以下是实际输出:

    expensive operation
 1st subscriber: 2;
expensive operation
 1st subscriber: 4;
expensive operation
 1st subscriber: 6;
expensive operation
 1st subscriber: 8;
expensive operation
 1st subscriber: 10;
expensive operation
 2nd subscriber: 2;
expensive operation
 2nd subscriber: 4;
expensive operation
 2nd subscriber: 6;
expensive operation
 2nd subscriber: 8;
expensive operation
 2nd subscriber: 10;
但为什么它在向所有订户发送之前重复昂贵的操作呢。对每个用户重复昂贵的操作?我正在使用share,因此我希望输出如下:

    expensive operation
 1st subscriber: 2;
 2nd subscriber: 2;
expensive operation
 1st subscriber: 4;
 2nd subscriber: 4;
expensive operation
 1st subscriber: 6;
 2nd subscriber: 6;
expensive operation
 1st subscriber: 8;
 2nd subscriber: 8;
expensive operation
 1st subscriber: 10;
 2nd subscriber: 10;
有趣的是,我发现只有在执行以下操作时,才会出现预期的输出:

var  ob1 = Observable.fromArray(1,2,3,4,5).map {
       println("expensive operation")
       it * 2
   }.publish()

    fun doMultiplyBy2(){
        ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}

        ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}

        ob1.connect()
    }
}
从而使其成为可连接的可观察对象,然后手动连接。为什么共享不起作用

更新:我想明确问题所在:

共享应该与publish().refCount()相同,我还以为共享会为我多播,但我看不到它会这样做。让我们看一看不是使用共享而是手动使用发布和连接:

 var  ob1 = Observable.fromArray(1,2,3,4,5).map {
       println("expensive operation")
       it * 2
   }.publish()

    fun doMultiplyBy2(){
        //ob1 = ob1.share()
        ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}

        ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}

        ob1.connect()
    }
}
其输出为:

expensive operation
 1st subscriber: 2;
 2nd subscriber: 2;
expensive operation
 1st subscriber: 4;
 2nd subscriber: 4;
expensive operation
 1st subscriber: 6;
 2nd subscriber: 6;
expensive operation
 1st subscriber: 8;
 2nd subscriber: 8;
expensive operation
 1st subscriber: 10;
 2nd subscriber: 10;
这正是我想要的。每次排放一次的昂贵操作

不允许将其更改为使用共享:

var  ob1 = Observable.fromArray(1,2,3,4,5).map {
       println("expensive operation")
       it * 2
   }.publish().refCount()//or can use share()

    fun doMultiplyBy2(){
        ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}

        ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
    }
}
这将产生以下输出:

    expensive operation
 1st subscriber: 2;
expensive operation
 1st subscriber: 4;
expensive operation
 1st subscriber: 6;
expensive operation
 1st subscriber: 8;
expensive operation
 1st subscriber: 10;
expensive operation
 2nd subscriber: 2;
expensive operation
 2nd subscriber: 4;
expensive operation
 2nd subscriber: 6;
expensive operation
 2nd subscriber: 8;
expensive operation
 2nd subscriber: 10;

如果publish().refCount()不像普通的可观察对象那样进行多播,那么它的目的是什么呢。它或共享有什么意义呢???

正如您所知
share
操作符是相同的
publish().refCount()
Refcount
使
成为可连接的观察者
。所以你的代码是正确的。但是您缺少的是
线程
。我想你能理解我想解释的内容。如果不让我知道

像这样更改代码

val ob1 = Observable.fromArray(1,2,3,4,5).map {
    println("expensive operation")
    it * 2
}.subscribeOn(Schedulers.computation()).share() 
// Add subscribeOn operator to change emitting thread from MAIN to WORK

fun doMultiplyBy2() {
    ob1.flatMap { Observable.just(" 1st subscriber: $it;") }.subscribe{println(it)}

    ob1.flatMap { Observable.just(" 2nd subscriber: $it;") }.subscribe{println(it)}
}

doMultiplyBy2()

Thread.sleep(1000) // Waiting for ending to execute
输出

expensive operation
 1st subscriber: 2;
 2nd subscriber: 2;
expensive operation
 1st subscriber: 4;
 2nd subscriber: 4;
expensive operation
 1st subscriber: 6;
 2nd subscriber: 6;
expensive operation
 1st subscriber: 8;
 2nd subscriber: 8;
expensive operation
 1st subscriber: 10;
 2nd subscriber: 10;
refCount()
相当于
refCount(1)
,这意味着当一个订户订阅时,可观察对象将开始执行

在下面的例子中:

var ob1=obobobable.fromArray(1,2,3,4,5).map{
println(“昂贵的操作”)
它是*2
}
.publish().refCount(1)//或.share()或.publish().refCount()
ob1.flatMap{Observable.just(“第一个订户:$it;”)}
.订阅{println(it)}
ob1.flatMap{Observable.just(“第二个订户:$it;”)}
.订阅{println(it)}
情况就是这样:

Observable has 0 subscribers  
Subscriber 1 subscribes  
Observable has 1 subscriber; refCount(1) condition is satisfied  
Observable EXECUTES EXPENSIVE OPERATION
Subscriber 1 executes onNext()  
Subscriber 1 executes onComplete() and unsubscribe  
Observable has 0 subscribers  
Subscriber 2 subscribes  
Observable has 1 subscriber; refCount(1) condition is satisfied  
Observable EXECUTES EXPENSIVE OPERATION
Subscriber 2 executes onNext()  
Subscriber 2 executes onComplete() and unsubscribe  
Observable has 0 subscribers  
Observable has 0 subscribers
Subscriber 1 subscribes
Observable has 1 subscriber
Subscriber 2 subscribes
Observable has 2 subscribers; refCount(2) condition is satisfied
Observable EXECUTES EXPENSIVE OPERATION
Subscriber 1 executes onNext()
Subscriber 2 executes onNext()
Subscriber 1 executes onComplete() and unsubscribe
Observable has 1 subscriber
Subscriber 2 executes onComplete() and unsubscribe
Observable has 0 subscribers
如果希望可观察对象等待有2个订户,则必须增加到
refCount(2)

在下面的例子中:

var ob1=obobobable.fromArray(1,2,3,4,5).map{
println(“昂贵的操作”)
它是*2
}

.publish().refCount(2)//
.share()
是一个运算符,它获取一个可观察对象并返回一个新对象。您订阅了两次非共享的可观察对象,创建并丢弃了共享的可观察对象。如果共享返回了一个新的可观察对象,那么为什么这对我不起作用:var ob1=obable.fromArray(1,2,3,4,5).map{println(“昂贵的操作”)it*2}.share()fun doMultiplyBy2(){ob1.flatMap{observatable.just(“第一订户:$it;”)}.subscribe{println(it)}ob1.flatMap{observatable.just(“第二订户:$it;”)}.subscribe{println(it)}//ob1.connect()请不要将代码放在评论中。编辑您的问题并将其添加到结尾。如果您可以更新您的问题,这将是一个理想的选择,但只是为了让您知道。您编写的代码很可能是同步运行的-因此它的行为正确。您需要一个非同步源来查看您想要的行为。嘿,谢谢您的帮助。我更新了我的问题。希望您能帮助我了解更多。因此
.share()
当运行在不同线程上的可观察对象订阅时,仅多播?是否有一个操作符总是多播,即使来自同一线程的可观察对象订阅时也是如此?