为了学习hytrix,先大致学习一下RxJava。
package com.liyao.rxJava;
import com.google.common.collect.Lists;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.Scheduler;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.exception.ExceptionUtils;
import java.util.List;
/**
* 根据官网介绍,Rx是一个基于事件的异步编程框架。实现方式借助的是观察者模式。
*
* 我们可以先看一个例子来理解。我们先构建Observable对象即被观察者对象,然后使用该对象发送3个事件,最终这3个事件会发送给Observer实例,即
* 观察者实例来处理。处理函数就是onNext,如果处理过程中发生异常,就会执行onError方法。
* 被观察者对象发送事件,对应了上面的“基于事件”;另外这个例子没有体现,通常的话,观察者的相应会放入新的线程处理,也就是所谓的“异步”。
*
*/
public class Main {
public static void main(String args[]) {
test3();
}
/**
* 下面看下这个例子。使用create方法可以创建一个被观察者,传入一个ObservableOnSubscribe参数。然后调用subscribe方法通知观察者,观察者直接使用
* 匿名内部类实现。这个调用过程深究其实很绕。这里面其实涉及到了四组角色。
* Observable:被观察者;
* ObservableOnSubscribe:姑且理解为发送的事件脚本,主要定义了有多少事件,或者说有多少参数要处理;
* ObservableEmitter:事件发送器,一个观察者的代理,需要传入一个观察者,通过ObservableEmitter来调用观察者的处理函数OnNext。
* Observer:观察者。
*
* 从实现上看,rx是一种观察模式,被观察者发送离散的事件,而观察者处理事件,是一种回调机制。
* 从使用上看,rx其实就是一个调用,被观察者发送的事件就是入参,观察者的处理就是对入参处理的函数。但是rx提供了产生参数和处理参数分割到不同
* 线程的能力。从形式上,是链式调用,很容易被阅读和理解,即便是多线程的场景,比我们自己用线程的api要好理解的多。这就是rx的优点。
*
* 这个调用过程:create只定义事件,而subscribe才是真正发送事件。subscribe一旦调用,Observable就会新建一个发射器ObservableEmitter,然后
* 以发射器为参数,调用ObservableOnSubscribe的subscribe,也就是事件脚本。接着事件发射器就是代理,最终会调用到Observer的处理函数。
* 从实现看,确实是一种观察者模式。
*/
public static void test1(){
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("Event1");
observableEmitter.onNext("Event2");
observableEmitter.onNext("Event3");
observableEmitter.onComplete();
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
System.out.println("subscribe");
}
@Override
public void onNext(String s) {
System.out.println("handle " + s);
}
@Override
public void onError(Throwable throwable) {
System.err.println("err occur" + ExceptionUtils.getStackTrace(throwable));
}
@Override
public void onComplete() {
System.out.println("complete");
}
});
}
/**
* 这是另外两种构建Observable的方式,省去了create。
*/
public static void test2(){
Observable.just("A", "B", "C").subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
String[] array = {"A", "B", "C"};
Observable.fromArray(array).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
/**
* rx提供了类似java stream的api来流式处理事件,其中的map和flatMap与stream含义相同
*/
public static void test3(){
class Person{
int age;
List<String> address;
}
Person p1 = new Person();
p1.age = 20;
p1.address = Lists.newArrayList("shanxi", "beijing");
Observable.just(p1).map(p->p.age).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
System.out.println("age: " + integer);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
Observable.just(p1).flatMap(p->Observable.fromIterable(p.address)).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String address) {
System.out.println("address: " + address);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
/**
* 可以指定事件发射和事件处理的线程,可以使用Schedulers提供的线程池。
* Schedulers.trampoline(): 当前线程。
* Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
* Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
* Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
*/
public static void test4(){
Observable.just("A")
.subscribeOn(Schedulers.trampoline())
.observeOn(Schedulers.computation())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}