demo
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onNext("4");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.d(TAG, "s = " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG, "完成 ");
}
});
线程池
严格意义上来讲,线程在线程池上操作只是当前Rxjava2中的一小部分,我们还是从架构层面去学习Rxjava2线程的操作。
需求:我们需要考虑哪些因素?
-
因为实际执行线程可能是线程池,也可能直接使用线程,还可能是其他,所以我们需要定义多类型线程或者线程池;
-
执行线程可能是一次性线程,执行完毕移除,也可能是定时任务线程,还可以加延时方案;
-
其他。在理解架构的基础上认证查看代码。
架构设计
-
新建一个调度器基类,调度器中新建一个工作线程基类,去完成不同任务线程:定时任务线和一次性任务;这两个任务都支持延时;
-
新建不同调度器,并且在不同调度器中新建不同工作线程;
代码实现
-
创建调度器基类,该基类用于创建基类工作线程,工作线程执行任务:一次性任务和定时任务;
public abstract class Scheduler { //创建工作线程 public abstract Worker createWorker(); //创建工作线程,使用工作线程执行 一次性任务线程 public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) { final Worker w = createWorker(); final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); DisposeTask task = new DisposeTask(decoratedRun, w); w.schedule(task, delay, unit); return task; } //当前任务表示执行一次性任务:重点看run方法,执行完毕将当前线程设置null static final class DisposeTask implements Disposable, Runnable, SchedulerRunnableIntrospection { @NonNull final Runnable decoratedRun; @NonNull final Worker w; @Nullable Thread runner; DisposeTask(@NonNull Runnable decoratedRun, @NonNull Worker w) { this.decoratedRun = decoratedRun; this.w = w; } @Override public void run() { runner = Thread.currentThread(); try { decoratedRun.run(); } finally { dispose(); runner = null; } } @Override public void dispose() { if (runner == Thread.currentThread() && w instanceof NewThreadWorker) { ((NewThreadWorker) w).shutdown(); } else { w.dispose(); } } @Override public boolean isDisposed() { return w.isDisposed(); } @Override public Runnable getWrappedRunnable() { return this.decoratedRun; } } //执行定时任务 public Disposable schedulePeriodicallyDirect(@NonNull Runnable run, long initialDelay, long period, @NonNull TimeUnit unit) { final Worker w = createWorker(); final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); PeriodicDirectTask periodicTask = new PeriodicDirectTask(decoratedRun, w); Disposable d = w.schedulePeriodically(periodicTask, initialDelay, period, unit); if (d == EmptyDisposable.INSTANCE) { return d; } return periodicTask; } public abstract static class Worker implements Disposable { public Disposable schedule(@NonNull Runnable run) { return schedule(run, 0L, TimeUnit.NANOSECONDS); } //定时任务 public Disposable schedulePeriodically(@NonNull Runnable run, final long initialDelay, final long period, @NonNull final TimeUnit unit) { final SequentialDisposable first = new SequentialDisposable(); final SequentialDisposable sd = new SequentialDisposable(first); final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); final long periodInNanoseconds = unit.toNanos(period); final long firstNowNanoseconds = now(TimeUnit.NANOSECONDS); final long firstStartInNanoseconds = firstNowNanoseconds + unit.toNanos(initialDelay); Disposable d = schedule(new PeriodicTask(firstStartInNanoseconds, decoratedRun, firstNowNanoseconds, sd, periodInNanoseconds), initialDelay, unit); if (d == EmptyDisposable.INSTANCE) { return d; } first.replace(d); return sd; } } }
-
满足不同需求,创建不同调度器 - 重点还是为了创建不同工作线程;
-
(1)设定执行线程名称和线程优先级RxThreadFactory,代码比较简单,自行查看;
-
(2)HandlerScheduler:android使用Handler更新UI的调度器,也比较简单,代码自行查看;
-
(3)IoScheduler和NewThreadScheduler也比较常用;
-
使用不同调度器
.subscribeOn(Schedulers.io()) .observeOn(Schedulers.newThread())
- 如上demo所以,这里传递的都是
Scheduler
对象,在Schedulers中查看具体调用过程。
- 如上demo所以,这里传递的都是
总结
艹,我怎么感觉自己啥都没说,又好像说了很多的样子,还是能力有限,线程池这一块理解不够透彻,但是架构方面理解的还算到位!!!
关键3点:
-
从点到线:按照流程顺序,理解一遍实际线程池使用流程;
-
从线到面:按照流程顺序涉及到的类理解一遍;
-
从面到立体结构:包和类理解一遍。