文章首发公众号:Java架构师联盟,每日更新技术好文
背压
本节首先介绍什么是背压(Backpressure)问题,然后介绍背压问题的几种应对模式。
什么是背压问题
当上下游的流操作处于不同的线程时,如果上游弹射数据的速度快于下游接收处理数据的速度,对于那些没来得及处理的数据就会造成积压,这些数据既不会丢失,又不会被垃圾回收机制回收,而是存放在一个异步缓存池中,如果缓存池中的数据一直得不到处理,越积越多,最后就会造成内存溢出,这便是响应式编程中的背压问题。
一个存在背压问题的演示实例代码如下:
package com.crazymaker.demo.rxJava.basic;
//省略import
@Slf4j
public class BackpressureDemo {
/**
*演示不使用背压
*/
@Test
public void testNoBackpressure() throws InterruptedException {
//被观察者(主题)
Observable observable = Observable.create(
new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
//循环10次
for (int i = 0;i<10 ; i++) {
log.info("produce ->" + i);
subscriber.onNext(String.valueOf(i));
}
}
});
//观察者
Action1<String> subscriber = new Action1<String>() {
public void call(String s){
try {
//每消费一次间隔50毫秒
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("consumer ->" + s);
}
};
//订阅:observable与subscriber之间依然通过subscribe()进行关联
observable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(subscriber);
Thread.sleep(Integer.MAX_VALUE);
}
}
在实例代码中,observable发射操作执行在一条通过Schedulers.io()调度器获取的IO线程上,而观察者subscriber的消费操作执行在另一条通过Schedulers.newThread()调度器获取的新线程上。observable流不断发送数据,累积发送10次;观察者subscriber每隔50毫秒接收一条数据。
运行上面的演示程序后,输出的结果如下:
17:56:17.719 [RxIoScheduler-2] INFO c.c.d.r.b.Backpres