我在一个函数里面有一个observable。函数发生在某个队列中,即queueA中,observable用observerOn(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的onNext里面从类全局变量写read的时候,用observableOn的做法通常是什么?
谢谢大家!
由于你的 SomeClass
无法控制这些函数何时被调用或在什么线程上调用 答案是肯定的,由于它的被动性,你在这段代码中被设置为有并发问题。
显而易见的解决方法是在队列B中调度 writeToResource()
以避免竞赛条件。
另一个选择是使用 NSLock
(或 NSRecursiveLock
),并在写到资源之前锁定它,之后再解锁。
最好的做法是:当你在一个订阅函数的闭包中发生副作用时(在本例中是写到 commonResource
该关闭是 只是 副作用发生的地方。这将意味着取消被动的 writeToResource()
函数,而是传入一个由当前调用该函数的任何代码生成的Observable。