I was asked to implement a thread safe dictionary in swift, I used the common approach:
class MutableDictionary {
var dictionary: [String : Any] = [:]
var queue = DispatchQueue(label: "queue", attributes: .concurrent)
func object(for key: String) -> Any? {
queue.sync {
return dictionary[key]
}
}
func set(_ object: Any?, for key: String) {
queue.async(flags: .barrier) {
self.dictionary[key] = object
}
}
}
However, the following up question is:
- What's the difference with using
concurrent+barriervs just using aserialQueuefor setting in this case? - I did a testing on playground, I wrapped the get and set with 1000 time for loop, it turns out that the behavior for both serial and concurrent queue is almost the same.
- Why the setting always raise an error?

- What does concurrent queue do better in this case (for both get and set) compared to a serial queue?
- In iOS, when should I choose serial queue over concurrent queue? And vice-versa?

concurrent + barriercan run multiplereadat the same time.serial queuecan only run one task (read/write) at a time.the results are the same, or even that the
serial queueis better because you're using only one thread to run. You can only take advantage of theconcurrent + barrierimplementation when read/write operations happen on multiple thread/queue. In this case, theserial queueis better because you don't need to look and switch between queue/thread.Full source code, please?
Concurrent + barriermight be better or not, as in (2), sometimes if you can ensure all operations happen in the same thread, thenserial queueis better.It depends on your case, as mentioned in (2), (4). One more thing about
concurrent + barrier, sometimes it isn't a good choice as you think. Imagine:You're implementing a feature that needs to do a heavy write operation, for example, you're reading your dict and calculating a new value, and updating the dict. You wrap all of these steps in a
queue.async(flags: .barrier)block.You expect these steps are running in your thread (background thread) and it doesn't block the main queue from reading the dict to update UI. But it does block the main queue, right?
Readoperations from the main queue have to wait forbarrierblock to finish first.If your application consumes a lot of CPU, you may have to wait for OS to find the thread for your
updatesteps, which means you have to spend more time on it.