swift - observable.observeOn() 和公共资源的并发问题
问题描述
我在函数中有一个可观察的。该函数发生在某个队列 queueA 中,并且 observable 是通过 observeOn(schedulerB) 订阅的。在 onNext 中,我正在更改一个类变量。
在另一个函数中,我正在从不同的队列中更改同一个类变量。
这是一些代码来演示我的情况:
class SomeClass {
var commonResource: [String: String] = [:]
var queueA = DispatchQueue(label: "A")
var queueB = DispatchQueue(label: "B")
var schedulerB = ConcurrentDispatchQueueScheduler(queue: QueueB)
func writeToResourceInOnNext() {
let obs: PublishSubject<String> = OtherClass.GetObservable()
obs.observeOn(schedulerB)
.subscribe(onNext: { [weak self] res in
// this happens on queue B
self.commonResource["key"] = res
}
}
func writeToResource() {
// this happens on queue A
commonResource["key"] = "otherValue"
}
}
我的问题是,如果同时在两个地方修改 commonResource 是否可能存在并发问题?
在使用 observable 的 observable 中写入/读取 onNext 内部的类/全局变量的常见做法是什么?
谢谢大家!
解决方案
由于您SomeClass
无法控制何时调用这些函数或在哪些线程上回答是肯定的,因此由于其被动性质,您将在此代码中设置并发问题。
这里明显的解决方案是调度到里面writeToResource()
的队列 B 以避免竞争条件。
另一种选择是在写入资源之前使用NSLock
(或)并锁定它,然后再解锁它。NSRecursiveLock
最佳实践是:当您在订阅函数的闭包内发生副作用时(在这种情况下,写到commonResource
闭包是唯一发生副作用的地方。这意味着取消被动writeToResource()
函数,而是传入一个由当前调用该函数的任何代码生成的 Observable。
推荐阅读
- php - Create all combinations of array with keys
- json - Parsing JSON to fasta format with specific constraint
- python - MultiValueDictKeyError during form submission
- java - JavaFX Internationalization without FXML
- django - 从 Django 中的 db 获取单条记录
- ruby-on-rails - How to create a Rails gem with conditional dependency installation
- ajax - Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource (POST request with object)
- java - QM API 休息使用
- plotly-dash - 从 Dash 中的所有其他下拉列表中删除选项
- groovy - Java/groovy 中方括号 [:] 括起来的冒号是什么意思?