英文:
I have a singleton that can be accessed on multiple threads, should each of its array have a separate dispatch queue?
问题
我有一个名为FruitManager
的单例,它负责管理水果。它内部有3个数组,分别是favoriteApples
、favoritePeaches
和favoriteOranges
。这个单例可以在任何可以读取/写入这些数组的线程上访问。
传统上,我会在这里使用一个DispatchQueue
来帮助处理读者/写者问题,其中我允许并发读取,但使用调度障碍块来确保一次只有一个写操作发生。
我的问题是,我应该为这3个数组中的每一个都有一个DispatchQueue
(总共3个队列),还是只需要为整个类有一个调度队列,这样只要在写入favoriteApples
时就会有效地锁定对favoritePeaches
的写入?
英文:
Say I have a singleton, FruitManager
that looks after fruits. It has 3 arrays inside, favoriteApples
, favoritePeaches
, and favoriteOranges
. The singleton can be accessed on any thread where these arrays can be read/written to.
Conventionally I'd use a DispatchQueue
here to help the Reader/Writer problem, where I'd allow for concurrent reads but use a dispatch barrier block to make sure only one write action occurs at a time.
My question is, should I have a DispatchQueue
for each of the 3 arrays (3 queues total)? Or just 1 dispatch queue for the entire class that would effectively lock writes to favoritePeaches
if favoriteApples
is being written to?
答案1
得分: 1
关于一个读写器与每个集合一个读写器的问题,这可能并不重要。但有一些考虑因素:
- 仅使用一个读写器的潜在问题是一个集合上的阻塞将会阻塞它们全部。因此,如果在一个或多个集合的同步过程中进行了任何计算密集型操作,您可能希望为每个集合使用单独的读写器,以避免对其他集合的性能产生不利影响。
然而,无论如何,您都不希望在读写器模式中执行任何计算密集型操作。"写入者"是一个异步障碍,这意味着它将阻塞任何后续的"读取者",直到写入完成。如果从主队列访问读取者,这将对主线程(或您正在读取的任何位置)的性能产生不利影响。
因此,如果它是计算密集型的,您不会使用读写器模式。 (您可能会希望使用异步获取方法,从而摆脱读写器模式。)如果没有进行任何计算密集型操作,那么为每个集合使用单独的读写器的好处就不大。
- 如果这三个集合是完全独立的(正如您的简单示例所示),那么设置多个读写器是可以的。但如果这三个集合之间存在任何依赖关系(例如,您从一个集合中读取以更新另一个集合),代码可能很快变得混乱。
因此,总之,出于简单起见,我倾向于为整个类使用单个读写器。但如果您已经有一个线程安全的集合类,它在内部使用读写器(或者无论如何使用任何同步机制),那么在具有这三个集合的类中使用它可能是可以的(只要您的三个集合之间没有复杂的依赖关系)。
不用说,上述内容适用于多个线程共享的任何对象,而不仅仅是单例。您目前使用的单例事实上与当前问题无关。
英文:
In answer to the one reader-writer vs one for each collection, it probably doesn’t matter. But there are a few considerations:
- The only potential problem with only one reader-writer is that a block on one collection will block them all. So, if you’re doing anything computationally expensive in the synchronization of one or more of the collections, you might want a separate reader-writer for each so it doesn’t adversely affect the performance of the others.
Then again, you never want to do anything computationally expensive with reader-writer pattern, anyway. The “writer” is an asynchronous barrier, so that means that it will block any subsequent “readers” until the write is done. And if accessing the readers from the main queue, that will adversely affect the performance on the main thread (or from wherever you’re reading).
So, if it’s computationally expensive, you wouldn’t use reader-writer, anyway. (You’d probably want an asynchronous fetch method, breaking you out of the reader-writer pattern.) And if you’re not doing anything computationally expensive, then there’s little benefit to using separate reader-writer for each collection.
- Setting up multiple reader-writers is fine if the three collections are entirely independent (as your simple example might suggest). But if there are any dependencies between the three collections (e.g. you’re reading from one to update the other), the code as potential to quickly become a mess.
So, bottom line, I’d lean towards a single reader-writer for the whole class for the sake of simplicity. But if you already have a thread-safe collection class that is using reader-writer (or any synchronization mechanism, for that matter) internally, then that it’s probably fine to use that within this class that has these three collections (as long as you don’t have any hairy dependencies between your three collections).
Needless to say, the above applies to any object shared amongst multiple threads, not just to singletons. The fact that you happen to be using using a singleton is irrelevant to the question at hand.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论