前言
上一次学习了解了一些RxJava比较常用的操作符,这次来学习一下Rx的多线程操作.
Scheduler-调度器
If you want to introduce multithreading into your cascade of Observable operators, you can do so by instructing those operators (or particular Observables) to operate on particular Schedulers.
如果你想给你的操作符链添加多线程,你可以通知这些操作符(或特定的Observables)运行在指定的调度器上.
也就是说RxJava的多线程是由Schedulers操作的,接下去去了解一下.
调度器种类
RxJava中Schedulers有很多种
下表展示了RxJava中可用的调度器种类(RxAndroid中有多少暂时不知道):
调度器类型 | 效果 |
---|---|
Schedulers.computation( ) | 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量 |
Schedulers.from(executor) | 使用指定的Executor作为调度器 |
Schedulers.immediate( ) | 在当前线程立即开始执行任务 |
Schedulers.io( ) | 用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器 |
Schedulers.newThread( ) | 为每个任务创建一个新线程 |
Schedulers.trampoline( ) | 当其它排队的任务完成后,在当前线程排队开始执行 |
知道了Schedulser,那么接下去就要运用了.
下面介绍两个操作符,对,是操作符.
SubscribeOn
specify the Scheduler on which an Observable will operate
SubscribeOn 指定了Observable的调度器.
ObserveOn
specify the Scheduler on which an observer will observe this Observable
指定observer将会在哪个Scheduler观察这个Observable.
更具体的说ObserveOn指示一个Observable在一个特定的调度器上调用观察者的onNext, onError和onCompleted方法,
即影响的是subscribe()
里的操作.
简单来讲:
使用RxJava,你可以使用subscribeOn()指定被观察者代码运行的线程,使用observerOn()指定订阅者运行的线程:
可能还是不太看得懂,
来,show me the code:
--出自这里
myObservableServices.retrieveImage(url)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(bitmap -> myImageView.setImageBitmap(bitmap));
上述代码表示,在Subscriber前面执行的代码都是在I/O线程中运行。最后,操作view的代码在主线程中运行.
PS:AndroidSchedulers.mainThread()
是在Android中才有.
总的来说RxJava操作多线程还是比较简单方便的,而且容易控制.
暂时也就只会这么点,以后学习了再补充.
接下来应该是RxAndroid了,好开心.
参考
微信公众号
网友评论
Observable.from(urllist).flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String url) {
Logger.d("Url:"+url);
return requestContent(url);
}
}).subscribeOn(Schedulers.io())
.subscribe(new Action1<String>() {
@Override
public void call(String content) {
Logger.d("Thread:"+Thread.currentThread().getName());
}
});
运行后可以发现虽然使用了flatMap,但是request(url)方法在没有指定线程的情况下,所有发射出去的Observable都运行在同一个子线程中,且保持了顺序,Log也是按照顺序Url和Content一组一组的执行。
而如果request(url)添加了subscribeOn(schedulers.io())之后,观察log可以发现,每个observable顺序执行,但是结果符合flatMap的特性交替出现,并且log显示在不同子线程中。
通过上面观察我自己得出的结论是,如果不为request()指定线程的话,多个url是按顺序在一个子线程中进行请求,如果其中一个阻塞,会导致后面的等待很久。而如果为request()指定了线程的话,就可以在多个线程发出多个request(),这样执行效率高很多。
在Android中可以声明observerOn在Android主线程。
但是我现在跑的是java项目要用哪个线程去接收呢?
我现在用的interval和timer,subscribe都接收不到。。