我想在我的应用程序中实现锁定,让当时只有一个链片段执行而任何其他链片段彼此等待。
例如:
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
实现它,但这可能会导致死锁。
我觉得这很糟糕。你能推荐我什么?
答案 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可以由Obserever
和Schedulers.single()
的串行执行器建模,但更有经验的RxJava程序员可以提供更多的建议。