其中有一篇博客写的很精彩戳这里,这个非常简洁
还有一篇精彩博文戳这里,这个解释的非常通透
无论是java8的CompletableFuture还是RxJava都是基于观察者模式的。只不过Rxjava更强大,有更好的错误处理、中断机制、完成状态
package com.hfview;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import lombok.extern.slf4j.Slf4j;
/**
* 观察者和被观察者创建
*
* @author: zhw
* @since: 2019/3/15 09:36
*/
@Slf4j
public class RxJavaDemo1 {
public static void main(String[] args) {
//创建被观察者---方式1
Observable switcher1 = Observable.create(emitter->{
log.debug("Observable emit 1");
emitter.onNext("1");
log.debug("Observable emit 2");
emitter.onNext("2");
log.debug("Observable emit 3");
emitter.onNext("3");
log.debug("Observable emit 4");
emitter.onNext("4");
log.debug("Observable emit onComplete ");
emitter.onComplete();
});
//创建被观察者---方式2
//Observable switcher2 = Observable.just("on","off","on","on");
//创建被观察者---方式3
//String [] kk={"On","Off","On","On"};
//Observable switcher3 =Observable.fromArray(kk);
//创建观察者
switcher1.subscribe(new Observer() {
private Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
log.debug(" 观察者onSubscribe");
disposable = d;
}
@Override
public void onNext(String s) {
log.debug(" 观察者onNext:"+s);
if(s.equals("2")){
disposable.dispose();
}
}
@Override
public void onError(Throwable e) {
log.error(" 观察者onError",e);
}
@Override
public void onComplete() {
log.info(" 观察者onComplete");
}
});
}
}
假如没有 switcher1.subscribe() 这个操作,观察者不会调用各种释放Next
注意这里有个误解,应该是观察者订阅被观察者,但是为了链式调用的方便,就搞成被观察者订阅观察者了。
如果在观察者onNext方法中调用Disposable 的dispose方法,那么就可以终止获取,但是被观察者仍然继续生产,只是这个观察者不接受了
比如上面观察者中onNext方法只会打印到 观察者onNext:1 观察者onNext:2 剩下的却不打印了。
如果观察者在onNext中发生异常,那么会在onError自动捕获改异常
package com.hfview;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
/**
* 数据转换和线程切换
*
* @author: zhw
* @since: 2019/3/15 09:36
*/
@Slf4j
public class RxJavaDemo2 {
public static void main(String[] args) throws Exception{
CountDownLatch countDownLatch = new CountDownLatch(1);
long start = System.currentTimeMillis();
//创建被观察者---方式2
Observable
.just("11011","21011","31011","41011")
//.subscribeOn(Schedulers.newThread())//被观察者线程切换
//.observeOn(Schedulers.io())
.map(s->{
log.debug("map操作当前线程为:"+Thread.currentThread().getName());
return convert(s);//转换功能
})
/*.flatMap(new Function>() {
@Override
public ObservableSource apply(String s) throws Exception {
return Observable.fromArray(s.split("0"));
}
})*/
.observeOn(Schedulers.computation())
.subscribe(new Observer() {
private Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
log.debug(" 观察者调用onSubscribe:"+Thread.currentThread().getName());
disposable = d;
}
@Override
public void onNext(String s) {
sleep(2000);
log.debug(" 观察者接受数据onNext:"+s+" "+Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
log.error(" 观察者调用onError"+Thread.currentThread().getName(),e);
}
@Override
public void onComplete() {
log.info(" 观察者调用onComplete"+Thread.currentThread().getName());
countDownLatch.countDown();
}
});
countDownLatch.await();
long end = System.currentTimeMillis();
log.debug("主线程结束了,耗时:"+(end-start));
}
/**
* 模拟耗时操作
* @param s
* @return
*/
public static String convert(String s){
//sleep(2000);
return s+"1";
}
public static void sleep(int n){
try {
Thread.sleep(n);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
如果清楚java中Stream中的流处理,那么这里他它差不多
public final Observable map(Function super T, ? extends R> mapper)
在函数式编成中也有这个接口Function,他基本就是负责转换,他需要一个入参? super T 和一个出参 ? extends R
.map(s->{
log.debug("map操作当前线程为:"+Thread.currentThread().getName());
return convert(s);//转换功能
})
public static String convert(String s){
return s+"1";
}
比如上面就是完成将当前字符串+“1”。
public final Observable filter(Predicate super T> predicate);
和函数式接口Predicate一样一个入参,然后返回boolean。true就保留,false就剔除
回压或者背压:主要是处理如果被观察者产生时间过快,而观察者来不及处理,导致堆积,导致OOM的事情。
下面是一个例子:
package com.hfview;
import io.reactivex.Flowable;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import java.util.concurrent.CountDownLatch;
/**
* 支持回压的Flowable
*
* @author: zhw
* @since: 2019/3/15 09:36
*/
@Slf4j
public class RxJavaDemo3 {
public static void main(String[] args) throws Exception{
CountDownLatch countDownLatch = new CountDownLatch(1);
long start = System.currentTimeMillis();
final int length = 100000;
String[] arr = new String[length];
for(int i=0;i() {
private Subscription subscription;
private int count = 0;
@Override
public void onSubscribe(Subscription s) {
log.debug(" 观察者调用onSubscribe"+Thread.currentThread().getName());
subscription = s;
s.request(10);
}
@Override
public void onNext(String s) {
count++;
//sleep(200);
log.debug(" 观察者接受数据onNext:"+s+" "+Thread.currentThread().getName());
if(count!=0&&count%10==0){
log.debug("观察者再次请求数据10条,当前已经处理了:"+count+"条");
subscription.request(10);
}
}
@Override
public void onError(Throwable e) {
log.error(" 观察者调用onError"+Thread.currentThread().getName(),e);
}
@Override
public void onComplete() {
log.info(" 观察者调用onComplete"+Thread.currentThread().getName());
countDownLatch.countDown();
}
});
countDownLatch.await();
long end = System.currentTimeMillis();
log.debug("主线程结束了,耗时:"+(end-start));
}
/**
* 模拟耗时操作
* @param s
* @return
*/
public static String convert(String s){
return s+"1";
}
public static void sleep(int n){
try {
Thread.sleep(n);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
用法基本和Observable。
区别:
public void request(long n)
和public void cancel()
,意思也很明显,调用request(10),意思我只需要10个事件处理,被观察者收到命令后就产生10个。 cancel就是取消。package com.hfview;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
* //TODO 写注释
*
* @author: zhw
* @since: 2019/3/15 15:54
*/
@Slf4j
public class RxJavaDemo4 {
public static void main(String[] args) throws Exception{
long start = System.currentTimeMillis();
CountDownLatch countDownLatch = new CountDownLatch(1);
Observable observable1 = Observable.fromCallable(new Callable() {
@Override
public String call() throws Exception {
log.debug("被观察者生成字符串1");
sleep(3000);
return "1";
}
}).subscribeOn(Schedulers.newThread());
Observable observable2 = Observable.fromCallable(new Callable() {
@Override
public String call() throws Exception {
log.debug("被观察者生成字符串2");
sleep(3000);
return "2";
}
}).subscribeOn(Schedulers.newThread());;
Observable observable3 = Observable.fromCallable(new Callable() {
@Override
public String call() throws Exception {
log.debug("被观察者生成字符串3");
sleep(3000);
return "3";
}
}).subscribeOn(Schedulers.newThread());;
//Observable unionObservable = observable1.concatWith(observable2).concatWith(observable3);
Observable unionObservable = observable1.mergeWith(observable2).mergeWith(observable3);
unionObservable
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
log.debug(" 观察者获取数据:"+s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
countDownLatch.countDown();
}
});
countDownLatch.await();
long end = System.currentTimeMillis();
log.debug("主线程结束了,耗时:"+(end-start));
}
public static void sleep(int n){
try {
Thread.sleep(n);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
一共三个事件各自需要3S,现在使用响应式编成,最后只需要3S就完成操作