RxJava的Observable.subscriber()的onNext回调是否必须使用线程安全对象?

时间:2017-11-17 18:29:05

标签: rx-java rx-java2

这就是我的代码:

ArrayList<T> result = new ArrayList<T>();
observable.subscribe(result::add, <something here>, <something here>);

这不推荐吗? result应该是一个线程安全的结构吗?

2 个答案:

答案 0 :(得分:0)

我使用它没有非线程安全对象的问题,几乎没有问题。在维护良好的并发性实践时,我建议研究RxJava的Observables的其他方法。

答案 1 :(得分:0)

了解线程安全意味着什么很重要。

一种类型的线程安全性来自分区,仅来自对一个线程中的对象执行操作。在这种情况下,您处理的对象没有特殊的线程安全问题。

当您使用synchronizevolatile等来确保访问和修改的串行性质时,会出现另一种类型的线程安全。

在您的示例中,result不是线程安全的,但我们无法判断它是否被正确划分,从而使线程安全成为非问题。安全违规的例子:

  • 你的observable可以从不同的线程中通过它发出值。您需要确保使用SerializedSubject或类似内容以确保维护可观察的合同。
  • 在观察者链处于活动状态时使用result的任何代码都存在使用不安全的风险。

以下是如何划分result的访问权限:

Scheduler myScheduler; // have a known, single-threaded scheduler.
...
List<String> result;
...
observer
  .observeOn( myScheduler )
  .subscribe( List::add, err -> {},
     () -> { // do end of processing here
   });

使用observeOn()将确保单个线程负责向result添加元素。

要访问结果的内容,你需要a)等到观察者链完成,这可以在onCompleted()处理中发出信号,或者b)你需要在与观察者相同的线程上运行链