我在下面尝试过。
public static void main(String[] args) throws Exception {
Observable.interval(100L, TimeUnit.MILLISECONDS)
.onBackpressureDrop().subscribe(new Subscriber<Long>() {
@Override
public void onStart() {
request(1L);
}
@Override
public void onNext(Long t) {
System.out.println("received: " + t);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
request(1);
}
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
});
TimeUnit.SECONDS.sleep(10L);
}
我预计订阅者会收到项0, 10, 20, 30...
,因为onBackpressureDrop方法会在请求之前删除项目。
但结果是0, 1, 2, 3...
。
此外,我尝试了onBackpressureLatest()
,但结果是相同的,0, 1, 2, 3...
。
这在我看来与onBackpressureBuffer
相同。
我是否误解了这种方法? 如果是这样,我如何尝试使用onBackpressureDrop方法作为Javadoc中的大理石图?
答案 0 :(得分:2)
发生这种情况是因为你把一个()间隔()运行的线程放到了睡眠状态。一种可能的解决方案 - 添加observeOn(Scheduler,bufferSize)运算符:
Observable.interval(100L, TimeUnit.MILLISECONDS)
.onBackpressureDrop()
.observeOn(Schedulers.io(), 1)
.subscribe(new Subscriber<Long>() {
@Override
public void onStart() {
request(1L);
}
@Override
public void onNext(Long t) {
System.out.println("received: " + t);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
request(1);
}
@Override
public void onCompleted() {
System.out.println("onCompleted");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
});
Observable.empty().delay(1, TimeUnit.MINUTES).toBlocking().subscribe();
通过这种方式,您的订户可以使用最小缓冲区大小的io()调度程序运行,并且背压似乎有效:
收到:0
收到:11
收到:22
答案 1 :(得分:2)
onBackpressureDrop
在这里没有做任何事情,因为在这种特殊情况下没有“背压”。您在subscribe
方法中执行的操作是通过Observable.interval
方法在每次发射后休眠1秒来阻止创建新值的线程。因此Observable.interval
每100毫秒不生成一个值,但每秒只被强制执行一次!
我建议您在observeOn
和onBackpressureDrop
之间添加subscribe
,以便生成值以及您在subscribe
中执行的操作位于不同的主题上。要查看效果,请使用缓冲区大小较小的this overload(例如1)。据我所知,任何类型的调度程序都会这样做。