observable.observationOn()和公共资源的并发问题

问题描述 投票:2回答:1

我在一个函数里面有一个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的做法通常是什么?

谢谢大家!

swift concurrency rx-swift reactivex
1个回答
1
投票

由于你的 SomeClass 无法控制这些函数何时被调用或在什么线程上调用 答案是肯定的,由于它的被动性,你在这段代码中被设置为有并发问题。

显而易见的解决方法是在队列B中调度 writeToResource() 以避免竞赛条件。

另一个选择是使用 NSLock (或 NSRecursiveLock),并在写到资源之前锁定它,之后再解锁。

最好的做法是:当你在一个订阅函数的闭包中发生副作用时(在本例中是写到 commonResource 该关闭是 只是 副作用发生的地方。这将意味着取消被动的 writeToResource() 函数,而是传入一个由当前调用该函数的任何代码生成的Observable。

© www.soinside.com 2019 - 2024. All rights reserved.