latch.countDown()
}
}
threads.forEach { it.start() }
latch.await()
check(actuallyReceived.get() == 3)
}
}
执行上面代码,由于take
的结果不符合预期,总是会异常退出
看一下take的源码:
public final class ObservableTake extends AbstractObservableWithUpstream<T, T> {
final long limit;
public ObservableTake(ObservableSource source, long limit) {
super(source);
this.limit = limit;
}
protected void subscribeActual(Observer<? super T> observer) {
this.source.subscribe(new ObservableTake.TakeObserver(observer, this.limit));
}
static final class TakeObserver implements Observer, Disposable {
final Observer<? super T> downstream;
boolean done;
Disposable upstream;
long remaining;
TakeObserver(Observer<? super T> actual, long limit) {
this.downstream = actual;
this.remaining = limit;
}
public void onNext(T t) {
if (!this.done && this.remaining-- > 0L) {
boolean stop = this.remaining == 0L;
this.downstream.onNext(t);
if (stop) {
this.onComplete();
}
}
}
}
}
果然不出所料,remaining--
没有任何锁操作,无法保证线程安全。
The Observable Contract
Rx在对Observable的定义中已经明确告诉我们了:
Observables must issue notifications to observers serially (not in parallel). They may issue these notifications from different threads, but there must be a formal happens-before relationship between the notifications.
reactivex.io/documentati…
happens-before relationship 需要我们保证进入stream数据的先后顺序,避免并发行为。根据官方的解释,这样做可以避免一些有锁操作带来的性能下降,因此仅在必要的时候才确保线程安全。
操作符的线程安全
那么哪些操作符是线程安全的呢?
RxJava的操作符种类繁多,一个一个记忆很难,基本上可以按照这个原则区分:
- 操作单个Observable的操作符都不是线程不安全的,例如常用的 take(n)、map()、distinctUntilChanged() 等,但是带有scheduler参数的除外,例如 window(…, scheduler)、debounce(…, scheduler) 等
- 操作多个Observable的操作符是线程安全的,例如 merge()、combineLatest()、zip()
用代码描述大概是这种感觉:
fun operatorThreadSafety() = if (operator.worksWithOneObservable() &&
operator.supportsScheduling == false) {
Operator.NOT_THREAD_SAFE_AND_THAT_IS_OK
} else {
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!