關於rx.exceptions.MissingBackpressureException背壓

cash長什麼樣:

rx.exceptions.MissingBackpressureException
 at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.onNext(OperatorObserveOn.java:130)
 at rx.internal.operators.OperatorSubscribeOn$1$1$1.onNext(OperatorSubscribeOn.java:76)
 at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54)
 at rx.internal.operators.OperatorTake$1.onNext(OperatorTake.java:73)
 at rx.internal.operators.OnSubscribeTimerPeriodically$1.call(OnSubscribeTimerPeriodically.java:52)
 at rx.Scheduler$Worker$1.call(Scheduler.java:120)
 at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
 at java.util.concurrent.FutureTask.run(FutureTask.java:266)
 at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
 at java.lang.Thread.run(Thread.java:784)

 

異常原因:拋出MissingBackpressureException往往就是因爲,被觀察者發送事件的速度太快,而觀察者處理太慢,而且你還沒有做相應措施,所以報異常。

場景重現:
//被觀察者在主線程中,每1ms發送一個事件
Observable.interval(1, TimeUnit.MILLISECONDS)
//.subscribeOn(Schedulers.newThread())
//將觀察者的工作放在新線程環境中

.observeOn(Schedulers.newThread())
//觀察者處理每1000ms才處理一個事件
.subscribe(new Action1() {

@Override
public void call(Long aLong) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.w("TAG","---->"+aLong);
}
});

解決方案:
1)過濾(拋棄) :加onBackpressureDrop操作符即可,Observable產生的事件可能都是我們需要的,一般來說不會拋棄
代碼示例
Observable.interval(1, TimeUnit.MILLISECONDS)
                .onBackpressureDrop()
                .observeOn(Schedulers.newThread())
               .subscribe(new Subscriber() {

                    @Override
                    public void onStart() {
                        Log.w("TAG","start");
//                        request(1);
                    }

                    @Override
                      public void onCompleted() {

                      }
                      @Override
                      public void onError(Throwable e) {
                            Log.e("ERROR",e.toString());
                      }

                      @Override
                      public void onNext(Long aLong) {
                          Log.w("TAG","---->"+aLong);
                          try {
                              Thread.sleep(100);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  });


2)緩存:加操作符 onBackpressurebuffer 即可, 就是雖然被觀察者發送事件速度很快,觀察者處理不過來,但是可以選擇先緩存一部分,然後慢慢讀。 ==》相關類似的操作符:buffer,window...

代碼示例同上,換操作符即可

Observable.interval(1, TimeUnit.MILLISECONDS)
                .onBackpressurebuffer()
                .observeOn(Schedulers.newThread())
               .subscribe(new Subscriber() {

}

.......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章