在单例中使用Thread-Unsafe对象的正确方法是什么?

时间:2016-03-17 19:04:14

标签: objective-c multithreading cocoa-touch thread-safety

假设我们在单例对象上有一个NSMutableArray。显然可以从多个不同的线程调用单例对象。

假设我们需要单例的用户能够添加对象或删除对象。或许我们有一个自定义对象,我们需要设置和阅读。

处理这些案件的正确方法是什么?单例上的每个线程不安全属性是否都有自己的串行/并发队列,然后为NSMutableArray覆盖addObject和removeObject函数,将dispatch_sync包装读取,并在dispatch_async(到串行队列)或dispatch_barrier_async(到并发)中写入队列)?

1)每个线程不安全的属性是否需要自己的队列?或者它至少应该在性能方面有一个。如果多个属性共享同一个队列,那么它将比必要的慢。

2)在什么情况下不需要这种线程保护。自从?或者线程不安全的属性是否总是覆盖它们的setter和getter。

1 个答案:

答案 0 :(得分:1)

1) Does every thread-unsafe property need its own queue? Or should it at least have one in terms of performance. If multiple properties shared the same queue, it would be slower than necessary.

Depends entirely on how frequently you are pounding on the serialized APIs. Start with a simple model and then move to more complex if needed.

And keep in mind that the implementation isn't necessarily limited to just adding queues at whim.

You could also use a multiple-reader, one writer model. That would involve keeping an NSArray* copy of the mutable array's contents that the readers can simultaneously hit. If the mutable array's contents are changed, then you can (thread safety in mind) swap a new immutable copy of the mutable array for the existing NSArray * (could be done with an atomic @property or you could use a concurrent queue for all reads with a barrier for the swap operation).

Something like the above might make sense when either the array is relatively small (cheap copies) or there are many many times more reads than writes.

2) In what cases is this thread protection unnecessary. Ever? Or should thread-unsafe properties always have their setters and getter overwritten.

A mutable collection is always thread unsafe, even when operating in a "readonly" mode. Only immutable collections are thread safe.

So, yes, you need to make sure you serialize any operation that would cause a thread unsafe action.