Rxjava温故知新(八)------背压模式

https://github.com/ReactiveX/RxJava/wiki/Backpressure-(2.0)

1.前言

1.在Rxjava1.x中不存在背压模式
2.在RxJava2.x中产生了了背压模式

1.什么是背压模式

背压模式主要是为了解决上游发送大量的事件,下游处理不过来的情况,使用Flowable来操作。相比较Observable多了背压策略。
背压涉及到数据缓冲池,缓冲池大小为128

2.背压的使用

因为使用背压模式就不得不使用到背压的模式,所以下面根据提供的几种背压模式来说明,背压模式采用Flowable创建被观察者,
对应的观察者应该为Subscriber,也可以使用快捷简单的Consumer
和前面讲到的Observable对比如下

Observable -------> Observer
Flowable   -------> Subscriber

2.1 BackpressureStrategy.ERROR

说明
上游发送大量数据,下游处理不过来(发生了阻塞,常常出现在异步操作里面),放入缓存池(128大小) ,如果池子满了,就会抛出异常

例子

 Flowable.create(new FlowableOnSubscribe<String>() {
        @Override
        public void subscribe(FlowableEmitter<String> emitter) throws Exception {
            for (int i = 0; i < 200; i++) {  //
                emitter.onNext("===> " + i);
            }
            emitter.onComplete();
        }
    }, BackpressureStrategy.ERROR)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<String>() {
        @Override
        public void onSubscribe(Subscription s) {
            s.request(200); //请求发射的数据 如果小于上游发射的数据,则还有部分数据不能正常发射则会抛出异常
        }

        @Override
        public void onNext(String s) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.i(TAG, "onNext: " + s);
        }

        @Override
        public void onError(Throwable t) {
            Log.i(TAG, "onError: " + t);
        }

        @Override
        public void onComplete() {
            Log.i(TAG, "onComplete: ");
        }
    });

输出1 (由于在上面我们说明了,缓冲池大小为128,在此例子中,我们不间断的发射200条数据,采用异步的方式,下游会休眠1毫秒,这样就会导致,上游不断的发射数据,下游处理不过来,会往缓冲池存储,缓冲池满了以后,就会抛出异常。)

1572315942.919 I/MainActivity: onNext: ===> 0
1572315942.920 I/MainActivity: onNext: ===> 1
1572315942.921 I/MainActivity: onNext: ===> 2
1572315942.923 I/MainActivity: onNext: ===> 3
1572315942.924 I/MainActivity: onNext: ===> 4
1572315942.925 I/MainActivity: onNext: ===> 5
1572315942.927 I/MainActivity: onNext: ===> 6
1572315942.928 I/MainActivity: onNext: ===> 7
1572315942.929 I/MainActivity: onNext: ===> 8
1572315942.930 I/MainActivity: onNext: ===> 9
1572315942.932 I/MainActivity: onNext: ===> 10
1572315942.933 I/MainActivity: onNext: ===> 11
1572315942.934 I/MainActivity: onError: io.reactivex.exceptions.MissingBackpressureException: create: could not emit value due to lack of requests

案例2 下面我们修改一下上面的数据,再次验证

Flowable.create(new FlowableOnSubscribe<String>() {
        @Override
        public void subscribe(FlowableEmitter<String> emitter) throws Exception {
            for (int i = 0; i < 200; i++) {
                emitter.onNext("===> " + i);
            }
            emitter.onComplete();
        }
    }, BackpressureStrategy.ERROR)
//                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
            @Override
            public void onSubscribe(Subscription s) {
                s.request(200);
            }

            @Override
            public void onNext(String s) {
//                try {
//                    Thread.sleep(1);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            Log.i(TAG, "onNext: " + s);
        }

        @Override
        public void onError(Throwable t) {
            Log.i(TAG, "onError: " + t);
        }

        @Override
        public void onComplete() {
            Log.i(TAG, "onComplete: ");
        }
    });

这里我们注释掉了线程的切换,让程序在一个线程里面运行,注释掉了线程休眠1毫秒的操作,这个时候上游发射的数据,下游能够及时的处理,不会出现阻塞的情况。输出结果如下

1572316741.677 I/MainActivity: onNext: ===> 0
1572316741.677 I/MainActivity: onNext: ===> 1
1572316741.677 I/MainActivity: onNext: ===> 2
				(省略...太长了)
1572316741.683 I/MainActivity: onNext: ===> 197
1572316741.683 I/MainActivity: onNext: ===> 198
1572316741.683 I/MainActivity: onNext: ===> 199
1572316741.683 I/MainActivity: onComplete: 

2.2 BackpressureStrategy.BUFFER

说明

上游发送大量数据,下游处理不过来 ,等待下游接收事件处理

例子 (还是采用上面的第一个例子,只是背压模式改成了Buffer)

	Flowable.create(new FlowableOnSubscribe<String>() {
        @Override
        public void subscribe(FlowableEmitter<String> emitter) throws Exception {
            for (int i = 0; i < 200; i++) {
                emitter.onNext("===> " + i);
            }
            emitter.onComplete();
        }
    }, BackpressureStrategy.BUFFER)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<String>() {
                @Override
                public void onSubscribe(Subscription s) {
                    s.request(200);
                }

                @Override
                public void onNext(String s) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.i(TAG, "onNext: " + s);
                }

                @Override
                public void onError(Throwable t) {
                    Log.i(TAG, "onError: " + t);
                }

                @Override
                public void onComplete() {
                    Log.i(TAG, "onComplete: ");
                }
            });

输出 (可以看到改成Buffer以后,上游处理不过来的时候会等待下去,直到全部处理完成)

1572317529.486 I/MainActivity: onNext: ===> 0
1572317529.487 I/MainActivity: onNext: ===> 1
1572317529.488 I/MainActivity: onNext: ===> 2
	(部分省略。。。。)
1572317529.770 I/MainActivity: onNext: ===> 195
1572317529.771 I/MainActivity: onNext: ===> 196
1572317529.773 I/MainActivity: onNext: ===> 197
1572317529.774 I/MainActivity: onNext: ===> 198
1572317529.775 I/MainActivity: onNext: ===> 199
1572317529.776 I/MainActivity: onComplete: 

2.3 BackpressureStrategy.DROP(不常用)

说明

上游发送大量数据,下游处理不过来 放入缓存池 ,如果池子满了,就会把后面的数据丢弃

例子

Flowable.create(new FlowableOnSubscribe<String>() {
        @Override
        public void subscribe(FlowableEmitter<String> emitter) throws Exception {
            for (int i = 0; i < 200; i++) {
                emitter.onNext("===> " + i);
            }
            emitter.onComplete();
        }
    }, BackpressureStrategy.DROP)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<String>() {
                @Override
                public void onSubscribe(Subscription s) {
                    s.request(200);
                }

                @Override
                public void onNext(String s) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.i(TAG, "onNext: " + s);
                }

                @Override
                public void onError(Throwable t) {
                    Log.i(TAG, "onError: " + t);
                }

                @Override
                public void onComplete() {
                    Log.i(TAG, "onComplete: ");
                }
            });

输出

1572318474.529 I/MainActivity: onNext: ===> 0
1572318474.531 I/MainActivity: onNext: ===> 1
				(省略。。。。)
1572318474.699 I/MainActivity: onNext: ===> 125
1572318474.702 I/MainActivity: onNext: ===> 126
1572318474.703 I/MainActivity: onNext: ===> 127 (缓冲池满了就会丢弃掉后面的数据)
1572318474.704 I/MainActivity: onComplete: 

2.4 BackpressureStrategy.LATEST(不常用)

说明

注释说明:Keeps only the latest onNext value, overwriting any previous value if the  downstream can't keep up.
上游发送大量数据,下游处理不过来 ,只存储128条数据,最后还会发送最后一条数据

例子

Flowable.create(new FlowableOnSubscribe<String>() {
        @Override
        public void subscribe(FlowableEmitter<String> emitter) throws Exception {
            for (int i = 0; i < 150; i++) {
                emitter.onNext("===> " + i);
            }
            emitter.onComplete();
        }
    }, BackpressureStrategy.LATEST)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<String>() {
                @Override
                public void onSubscribe(Subscription s) {
                    s.request(150);
                }

                @Override
                public void onNext(String s) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.i(TAG, "onNext: " + s);
                }

                @Override
                public void onError(Throwable t) {
                    Log.i(TAG, "onError: " + t);
                }

                @Override
                public void onComplete() {
                    Log.i(TAG, "onComplete: ");
                }
            });

输出(可以看到在最后输出了128条数据以后,最后还发送了一条149的数据,149在发送的数据里面就是最后一条也是最新的一条数据,也会被打印出来)

1572330316.528 I/MainActivity: onNext: ===> 0
1572330316.540 I/MainActivity: onNext: ===> 1
				(省略。。。。)
1572330317.889 I/MainActivity: onNext: ===> 126
1572330317.900 I/MainActivity: onNext: ===> 127
1572330317.910 I/MainActivity: onNext: ===> 149

3.结尾

//背压四种模式 (缓存池128)
//1.BackpressureStrategy.ERROR   //上游发送大量数据,下游处理不过来,放入缓存池 ,如果池子满了,就会抛出异常
//2.BackpressureStrategy.BUFFER  //上游发送大量数据,下游处理不过来 ,等待下游接收事件处理
//3.BackpressureStrategy.DROP(不常用) //上游发送大量数据,下游处理不过来 放入缓存池 ,如果池子满了,就会把后面的数据丢弃
//4.BackpressureStrategy.LATEST(不常用) //上游发送大量数据,下游处理不过来 ,只存储128条数据,最后还会发送最后一条数据


通过 Subscription.request(n) 方法,请求发射的数量
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章