V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanck0605
V2EX  ›  Java

RxJava 的 onNext 访问资源时,否需要考虑线程安全。

  •  1
     
  •   fanck0605 · 2021-11-29 17:32:05 +08:00 · 1593 次点击
    这是一个创建于 873 天前的主题,其中的信息可能已经有所发展或是发生改变。

    《 RxJava 反应式编程》中有提到( P7 ),按照契约 ObverseronNext 函数是不会同时被多条线程调用的,这不就意味着不存在对临界资源的争抢。那么后文(P71)又说需要保证 lambda 表达式(total::add)内访问变量的线程安全性。

    如果这个资源(total 变量,如果不是 atomic 的), 只会被这一个 Obverser 访问,那么还需要考虑线程安全问题吗。

    P7

    oMXnSA.jpg

    p71

    oMXlef.md.jpg

    7 条回复    2021-12-05 22:05:01 +08:00
    shyling
        1
    shyling  
       2021-11-29 18:33:25 +08:00
    下面的例子举的不对。。。

    他的意思应该是让最好用 scan 累加结果,而不是用外部的 adder 。。。但这个例子跑起来也没问题。
    shyling
        2
    shyling  
       2021-11-29 18:34:34 +08:00
    如果 adder 不线程安全,结果也是对的。onNext 是顺序调用的
    fanck0605
        3
    fanck0605  
    OP
       2021-11-29 20:13:27 +08:00
    @shyling
    onNext 虽然是顺序调用的, 但需不需要考虑变量不可见 (volatile 关键词) 的问题呢?

    毕竟 onNext 并没有保证是在同一条线程运行。
    fanck0605
        4
    fanck0605  
    OP
       2021-11-29 20:24:17 +08:00
    我编写了这样的一段代码,虽然不加 volatile 结果是正确的,但是我仍然不确定 volatile 是否是必要的

    ![oQJzh6.md.png]( https://z3.ax1x.com/2021/11/29/oQJzh6.md.png)
    chihiro2014
        5
    chihiro2014  
       2021-11-30 10:07:51 +08:00
    如果变量是全局的,那就需要加 volatile 。局部就不需要 @fanck0605
    fanck0605
        6
    fanck0605  
    OP
       2021-12-02 19:37:59 +08:00
    看了一下 JVM 的 happens-before 规则,onNext 前后好像都有内存屏障,毕竟一定用了锁或者 volatile 变量操作,所以 onNext 内访问的变量,无需加 volatile ,一定安全的。
    aboutlonger
        7
    aboutlonger  
       2021-12-05 22:05:01 +08:00
    我猜这个契约是要开发者去遵守的,不是 rxjava 作出的保证。

    即使这个资源只会被一个 Observer 访问,也是需要考虑线程安全的,因为一个 Observable 的 Scheduler 可以是一个线程池。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2766 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 15:12 · PVG 23:12 · LAX 08:12 · JFK 11:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.