如何在RxJava中实现链锁

时间:2018-06-05 03:40:30

标签: java kotlin rx-java rx-java2

我想在我的应用程序中实现锁定,让当时只有一个链片段执行而任何其他链片段彼此等待。

例如:

    val demoDao = DemoDao() // data that must be accessed only by one rx-chain fragment at one time

    Observable.range(0, 150)
            .subscribeOn(Schedulers.io())
            .flatMapCompletable {
                dataLockManager.lock("action") { // fragment-start
                    demoDao.get()
                        .flatMapCompletable { data ->
                            demoDao.set(...)
                        }
                }                                // fragment-end
            }
            .subscribe()

    Observable.range(0, 100)
            .subscribeOn(Schedulers.io())
            .flatMapCompletable {
                dataLockManager.lock("action") { // fragment-start
                    demoDao.get()
                            .flatMapCompletable { data ->
                                demoDao.set(...)
                            }
                }                                // fragment-end
            }
            .subscribe()

我尝试使用Completable.create通过自定义CountDownLatch实现它,但这可能会导致死锁。

我觉得这很糟糕。你能推荐我什么?

2 个答案:

答案 0 :(得分:2)

要序列化demoDao.get()的访问权限,有几种方法可以实现这一点但是尽量不要使用锁来执行此操作,因为这可能会为启动器填充带有死锁的反应流(如您所知) )。

如果您确实想使用锁定,则应确保流信号之间没有锁定,例如向下游发射或向上游请求。在这种情况下,您可以使用锁(短期)。

一种方法是将两个流的操作合并为一个(比如说merge)并在那一个流上执行demoDao个操作。

另一种方法是使用PublisheSubject创建PublishSubject.create().serialized()demoDao.get()执行下游.doOnNext(x -> subject.onNext())内容并仅订阅一次。然后你提到的两个来源可以PublishSubject。取决于每个来源是否必须独立了解故障,或者export interface User { id: number; name: string; more_complex_object: // so I am not sure how do this in right way. pass here another interface //or just a object like {id: '', name: ''}. I show how to do this in class way... } 订阅是否是唯一通知失败的地点。

答案 1 :(得分:0)

在异步世界中,强烈建议不要使用锁。相反,锁定是通过序列化执行actor或串行执行器来建模的。反过来,actor可以由ObsereverSchedulers.single()的串行执行器建模,但更有经验的RxJava程序员可以提供更多的建议。