平行流、字符串、实用操作符

介绍:

2.0.5版本引入的ParallelFlowable API 允许并行执行一系列选择的操作符,例如 map,filter,concatMap,flatMap,collect,reduce 等等。 注意:对于Flowable(一个特定的子域语言)这是一个并行的模块而不是新的响应基础类型。

因此,几个典型的操作符例如take,skip 和许多其他的是不可用的且这儿没有ParallelObservable ,因为 像期望那样内部的并行操作符队列不发生洪泛,背压是至关重要的,我们希望并行是因为单线程处理数据是缓慢的。

最简单的方式进入并行世界是使用 Flowable.parallel:

ParallelFlowable<Integer> source = Flowable.range(1, 1000).parallel();

默认情况下,并行级别被设置为可用的cpu数量。

(Runtime.getRuntime().availableProcessors()) 和 从原序列预取的数量 被设置到Flowable.bufferSize() (128).两者都可以通过parallel()的重载函数来指定。

ParallelFlowable 遵循Flowable同样的异步参数原则,因此, parallel() 本身不引入源序列的异步消费,但仅准备并行流,异步通过runOn(Scheduler) 操作符被定义。

ParallelFlowable<Integer> psource = source.runOn(Schedulers.io());

并行等级(ParallelFlowable.parallelism()) 不必匹配Scheduler的并行等级。runOn操作符将使用和并行源定义的一样多的Scheduler.Worker实例。 这允许ParallelFlowable 为CPU密集的任务工作通过Schedulers.computation(),阻塞IO 通过Schedulers.io() 绑定任务且通过TestScheduler单元测试。你也可以指定预取数量在runOn上。

一旦必要的平行操作已经被应用,你可以通过ParallelFlowable.sequential()操作符返回连续的Flowable

Flowable<Integer> result = psource.filter(v -> v % 3 == 0).map(v -> v * v).sequential();

注意: sequential 不保证在并行运算符之间流动的值之间的顺序。

String Observables

StringObservable 类包含一些函数,这些函数代表一些操作符,特别是处理基于字符串的序列和流的Obseravable.这些包括:

  • byLine( )— 通过把源序列处理为一个流且以换行符为分割来把一个Observable的字符串转换成行的Observable
  • decode( )— 把一个多字节字符转换成一个发射遵守字符边界的字节数组的Observable
  • encode( )— 把一个发射字符串的Observable转换成一个遵守源字符串中多字节字符的字符边界的字节数组的Observable.
  • from( )— 转换一个字符流或者一个Reader 为一个发射字节数组或者字符串的Observable.
  • join( )— 把一个发射字符串序列的Observable转换成一个发射一个单一字符串,该字符串是由那些字符串序列拼接而成。
  • split( )— 把一个Observable的字符串转换成一个Observable,这个Observable把源序列当做一个流,且该流是以特定正则边界分割开
  • stringConcat( )— 把一个发射一系列字符串的Observable转换成一个发射由上述字符串序列拼接成的单一字符串的Observable

Transforming Observables

这部分说明你可以转换被Observable发射的item的操作符

  • map( )— 通过对每一个被Observable发射的item应用一个函数来转换他们
  • flatMap( )****, ****concatMap( )****, and ****flatMapIterable( ) —把被Observable发射的多个item转换成多个Observable或多个Iterable,接着压成一个单一的Observable.
  • switchMap( )— 把被Observable发射的多个item转换成多个Observable,并且镜像那些最近被转换的Observable发射的item
  • scan( )— 对每一个被Observable发射的item值应用一个函数,且发射后续的每一个值。
  • groupBy( )— 把一个Observable划分成一系列通过key组织的Observable,这些Observable从原始的Observable发射成群的item。
  • buffer( )— 周期性的从一个Observable聚集item成一个bundle,且发射这些bundle而不是一次发射一个item。
  • window( )— 周期性的从一个Obseravble再细分item成一个Observable window 且发射这些Window而不是一次发射一个item.
  • cast( )— 在再次发射他们之前,把来自于源Observable的所有item转换成特殊的类型。

Observable Utility Operators

这部分列出了不同的为Observable工作的实用操作符。

  • materialize( )— 把一个Observable转换一系列通知。
  • dematerialize( )— 把一个物化的Obsrevable回退到非物化的形式
  • timestamp( )— 为每一个被Observable发出的item附上时间戳
  • serialize( )— 强制一个Observable执行序列化调用
  • cache( )— 记住被Observable发射的item序列且为未来的订阅者发射相同的序列。
  • observeOn( )— 指定Subscriber应该在哪个Scheduler观察Observable.
  • subscribeOn( )— 当一个订阅被执行的时候,指定一个Observable应该使用哪个Scheduler。
  • doOnEach( )— 无论何时Observable发射一个item,注册一个action.去执行
  • doOnNext( )— 就在Observable传入onNext事件顺流而下之前,注册一个action去执行
  • doAfterNext( ) —就在Observable传入onNext事件顺流而下之后,注册一个action去执行
  • doOnCompleted( )— 当一个Observable成功完成,注册一个action去执行
  • doOnError( )— 当一个Observable带错误完成,注册一个action去执行
  • doOnTerminate( )— 在一个Observable结束之前,不管成功或是出错,注册一个action去调用。
  • doAfterTerminate( )— 在一个Observable结束之后,不管成功或是出错,注册一个action去调用。
  • doOnSubscribe( )— 当一个Observabler订阅一个Observable,注册一个action去调用。
  • 1.xdoOnUnsubscribe( ) — 当一个Observable取消订阅一个Observable,注册一个action去调用
  • finallyDo( )— 当一个Observable完成,注册一个action去执行。
  • doFinally( )— 当一个Observable结束或者被处理,注册一个action去执行
  • delay( )— 从一个Obseravble按一定数量向将来转移一些发射对象
  • delaySubscription( )— 持有一个Subscriber的订阅请求一段指定的时间在传入它到源Observable之前。
  • timeInterval( )— 在源Observable的两个连续的发射之间暂停一段时间
  • using( )— 创建一个与Observable相同生命周期的可支配的资源
  • single( )— 如果Observable再发射一个item后完成了,那么返回这个item,否则抛出一个异常
  • singleOrDefault( ) —如果Observable再发射一个item后完成了,那么返回这个item,否则返回默认item
  • repeat( )— 创建一个重复发射特殊item或者item序列的 Observable
  • repeatWhen( ) —创建一个重复发射特殊item或者item序列的 Observable,取决于第二个Observable的发射

Plugins

插件允许你从几个方面改变Rxjava默认的行为

通过改变一系列默认的计算,i/o 和新线程调度器

通过注册RxJava可能遇到的特别错误的处理器

通过注册能够注意到几个常规RxJava活动的发生的函数

RxJavaHooks

新的RxJavaHooks允许你连接到 Observable、Single、Completable类型及被Schedulers返回的Scheduler们 的生命周期 且为不可交付的问题提供一个全方位的解决方案。

你现在可以在运行期改变这些hook 且不必再通过系统参数准备hook。因此用户可能仍要依赖于旧的hook系统,RxjavaHooks 默认委托给旧的Hook。

RxJavaHook 有不同种类的hook的setter和getter

image.png

读取和改变这些hook是线程安全的

你也可以通过clear()清除所有的hook 或者 通过reset()重置到默认的行为(委托给旧的RxJavaPlugin系统)

例子:

RxJavaHooks.setOnObservableCreate(o -> { 
    System.out.println("Creating " + o.getClass());
    return o; 
});
try {
    Observable.range(1, 10)
    .map(v -> v * 2)
    .filter(v -> v % 4 == 0)
    .subscribe(System.out::println);
} finally {
    RxJavaHooks.reset();
}

此外,RxJavaHook 提供所谓的装配跟踪特性.这嵌入一个自定义Observable,Single,Completable到他们捕捉目前栈迹的链中 当这些操作符被实例化的时候(装配时间)。无论何时 一个错误信号通过onError被发出,这些附加到装配时间的栈轨迹的中间件最终造成这个异常。这可能帮助定位代码库的问题序列。

Example:

RxJavaHooks.enableAssemblyTracking();
try {
    Observable.empty().single()
    .subscribe(System.out::println, Throwable::printStackTrace);
} finally {
   RxJavaHooks.resetAssemblyTracking();
}

这将打印像下面的结果:

java.lang.NoSuchElementException
at rx.internal.operators.OnSubscribeSingle(OnSubscribeSingle.java:57)
...
Assembly trace:
at com.example.TrackingExample(TrackingExample:10)

栈轨迹字符串在支持debug和发现运行链中不同操作符的状态也是可用的。

栈轨迹通过移除不相关的入口例如线程入口,单元测试和跟踪系统入口本身 来被过滤去减少噪音

RxJavaSchedulersHook

Deprecated

这个插件允许你去重载默认的计算,i/o 和新线程Scheduler .集成 类RxJavaSchedulersHook 和重写如下方法 :

  • Scheduler getComputationScheduler( )
  • Scheduler getIOScheduler( )
  • Scheduler getNewThreadScheduler( )
  • Action0 onSchedule(action)

接着按如下步骤:

  1. 创建一个新的你已经实现的RxJavaDefaultSchedulers 子类的对象

  2. 通过RxJavaPlugins.getInstance( )获取全局的RxJavaPlugins 实例

  3. 传入默认的scheduler对象到该实例的registerSchedulersHook( )函数

当你完成了这些,RxJava 开始使用你的函数返回的Scheduler而不是它内嵌的默认的

RxJavaErrorHandler

Deprecated

该插件允许你注册一个将会处理错误的函数,该错误将被传到SafeSubscriber.onError(Throwable)。(SafeSubscriber 用于封装即将到来的Subscriber当subscribe()被调用)。为此,继承类RxJavaErrorHandler``且 重写该函数:

  • void handleError(Throwable e)

接着按如下步骤:

  1. 创建一个你实现的RxJavaErrorHandler 子类的新的对象

  2. 通过RxJavaPlugins.getInstance( )获取全局的RxJavaPlugins 实例

  3. 传入错误处理器到该实例的registerErrorHandler( )函数

当你完成了这些,RxJava将开始使用你的错误处理器来处理传给SafeSubscriber.onError(Throwable)的错误。

例如:

RxJavaPlugins.getInstance().reset();

RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
    @Override
    public void handleError(Throwable e) {
        e.printStackTrace();
    }
});

Observable.error(new IOException())
.subscribe(System.out::println, e -> { });

然而,该调用和操作符链一般情况下将不会在每个阶段被触发。

Observable.error(new IOException())
.map(v -> "" + v)
.unsafeSubscribe(System.out::println, e -> { });

RxJavaObservableExecutionHook

Deprecated

该插件允许你注册RxJava将调用某些常规的RxJava活动的函数,例如:日志或者metrics-collection purposes。为此,继承RxJavaObservableExecutionHook 类 且重写这些方法中的任何一个或全部

image.png

接着按如下步骤:

  1. 创建一个新的你实现的RxJavaObservableExecutionHook 子类的实例。

  2. 通过RxJavaPlugins.getInstance( )或者全局的RxJavaPlugins 实例

  3. 传入你的执行hook对象到该实例的registerObservableExecutionHook( )函数中。

当你完成了这些,RxJava将会调用你的函数当遇到特定的被设计需要注意的条件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容