Android--RxJava之并发处理(SerializedSubject)

本文探讨了在Android开发中,如何在并发环境下正确使用RxJava的SerializedSubject,以确保线程安全。通过示例代码和源码分析,揭示了SerializedSubject如何保证同一时间只有一个线程调用onNext等方法,以及其内部实现原理,解释了并发执行结果并非全部在同一线程上的原因。
摘要由CSDN通过智能技术生成

在并发情况下,不推荐使用通常的Subject对象,而是推荐使用SerializedSubject,并发时只允许一个线程调用onnext等方法! 
官方说明:

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">When you use an ordinary Subject <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> a Subscriber, you must <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">take</span> care <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">to</span> call its Subscriber.onNext <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">method</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">or</span> its other <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">on</span> methods)</span> <span class="hljs-title" style="box-sizing: border-box;">from</span> <span class="hljs-title" style="box-sizing: border-box;">multiple</span> <span class="hljs-title" style="box-sizing: border-box;">threads</span>, <span class="hljs-title" style="box-sizing: border-box;">as</span> <span class="hljs-title" style="box-sizing: border-box;">this</span> <span class="hljs-title" style="box-sizing: border-box;">could</span> <span class="hljs-title" style="box-sizing: border-box;">lead</span> <span class="hljs-title" style="box-sizing: border-box;">to</span> <span class="hljs-title" style="box-sizing: border-box;">non</span>-<span class="hljs-title" style="box-sizing: border-box;">serialized</span> <span class="hljs-title" style="box-sizing: border-box;">calls</span>, <span class="hljs-title" style="box-sizing: border-box;">which</span> <span class="hljs-title" style="box-sizing: border-box;">violates</span> <span class="hljs-title" style="box-sizing: border-box;">the</span> <span class="hljs-title" style="box-sizing: border-box;">Observable</span> <span class="hljs-title" style="box-sizing: border-box;">contract</span> <span class="hljs-title" style="box-sizing: border-box;">and</span> <span class="hljs-title" style="box-sizing: border-box;">creates</span> <span class="hljs-title" style="box-sizing: border-box;">an</span> <span class="hljs-title" style="box-sizing: border-box;">ambiguity</span> <span class="hljs-title" style="box-sizing: border-box;">in</span> <span class="hljs-title" style="box-sizing: border-box;">the</span> <span class="hljs-title" style="box-sizing: border-box;">resulting</span> <span class="hljs-title" style="box-sizing: border-box;">Subject</span>. </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

大致意思是当我们使用普通的Subject,必须要注意不要在多线程情况下调用onNext 方法,这样是违反了Observable 协议并且会导致执行结果返回带有有歧义的值(线程并发导致返回值混淆了)!

<code class="hljs vbnet has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">To</span> protect a Subject <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> this danger, you can convert it <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">into</span> a SerializedSubject <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">with</span> code <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">like</span> the following: 

mySafeSubject = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SerializedSubject( myUnsafeSubject );
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

官方文档说的很明白了,只需要使用SerializedSubject封装原来的 
Subject即可!!

测试demo:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MultiThread</span> {</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> InterruptedException {

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> PublishSubject<Integer> subject = PublishSubject.create();

        subject.subscribe(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Action1<Integer>() {

            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">call</span>(Integer t) {
                System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"======onnext===>value:"</span> + t + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",threadId:"</span> + Thread.currentThread().getId());
            }

        });

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> SerializedSubject<Integer, Integer> ser = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SerializedSubject<Integer, Integer>(subject);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); b
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值