简介
RxJava是一个异步的框架,使用Scheduler调度器通过observeOn和subscribeOn这两个方法可以对线程进行控制
调度器种类
Schedulers.io( )
用于IO密集型任务的操作(读写文件、读写数据库、网络信息交互等),具有线程缓存机制,CoreSize为1,在此调度器接收到任务后,先检查线程缓存池中,是否有空闲的线程,如果有,则复用,如果没有则创建新的线程,并加入到线程池中,如果每次都没有空闲线程使用,可以无上限的创建新线程。
Schedulers.computation()
用于CPU 密集型计算任务,即不会被 I/O 等操作限制性能的耗时操作(xml、json文件的解析,Bitmap图片的压缩取样等),具有固定的线程池,默认线程数等于处理器的数量。不可以用于I/O操作,否则I/O操作等待时间会浪费cpu
Schedulers.newThread( )
总是启动新线程,在新的线程中执行操作,不具有线程缓存机制,因为创建一个新的线程比复用一个线程更耗时耗力,虽然使用Schedulers.io( )的地方,都可以使用Schedulers.newThread( ),但是Schedulers.newThread( )的效率没有Schedulers.io( )高
Schedulers.single()
拥有一个线程单例,所有的任务都在这一个线程中执行,当此线程中有任务执行时,其他任务将会按照先进先出的顺序依次执行
Schedulers.trampoline()
在当前线程立即执行任务,如果当前线程有任务在执行,则会将其暂停,等插入进来的任务执行完之后,再将未完成的任务接着执行
当其它排队的任务完成后,在当前线程排队开始执行
Schedulers.from(executor)
使用指定的Executor作为调度器,由此调度器来控制任务的执行策略
AndroidSchedulers.mainThread()
在Android UI线程中执行任务,为Android开发定制。使用MainLooper实现
指定线程
observerOn(Schedulers)
指定观察者Observer在哪个线程执行,当每次调用observeOn操作符时,之后的观察者都会在选择的调度器上进行观察
subscribeOn(Scheduler)
指定被观察者Observable在哪个线程执行,跟调用的位置没有关系,而且多次调用并不会起作用,只有第一次调用时指定的调度器有效
计时器线程
timer、delay、interval、intervalRange等时间操作符的线程调度器是Schedulers.computation(),即使指定了subscribeOn(Schedulers)也无法改变其线程,只能指定观察者observerOn(Schedulers)的执行线程。如果有多个且延时周期短的interval计时器任务时,需要注意指定观察者的线程调度器,因为Schedulers.computation()调度器的线程数是CPU核心数,数量有限如果被计时器任务调度了,将导致其它计时任务或指定Schedulers.computation()调度器的任务阻塞或延时时间不精准等问题
Observable.interval(5, 1, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.i("--->", "interval " + Thread.currentThread().getName());
}
});
输出结果:interval RxComputationThreadPool-3 (即使指定了subscribeOn也无法改变其调度器)
Observable.interval(5, 1, TimeUnit.SECONDS).observeOn(Schedulers.io()).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.i("--->", "interval " + Thread.currentThread().getName());
}
});
输出结果:interval RxCachedThreadScheduler-2 (指定了observerOn观察者线程调度器,避免Schedulers.computation被用于耗时操作导致其它任务被阻塞)