MiddleCodeCommonNot answered yet
Make a shared cache thread-safe with a concurrent queue and a barrier write
Make this key-value cache thread-safe. Concurrent reads must run in parallel, but a write must be exclusive — no read or other write may overlap it.
Constraints:
- Use one private concurrent
DispatchQueue. - Reads run concurrently; writes use a barrier.
- Do not serialize reads against each other.
final class Cache {
private var storage: [String: Data] = [:]
func value(for key: String) -> Data? {
// your code here
}
func set(_ value: Data, for key: String) {
// your code here
}
}
Write the implementation.
Use a private concurrent DispatchQueue. Reads use queue.sync and run in parallel; writes use queue.async(flags: .barrier), running alone. Plain sync lets a write overlap concurrent reads — only .barrier makes it exclusive.
- ✗Thinking a plain
syncread makes concurrent writes exclusive - ✗Using
.barrieron reads, which pointlessly serializes them - ✗Believing FIFO ordering alone makes concurrent access safe
- →Why must reads use
syncrather thanasyncto return a value? - →What happens to reads queued after a
.barrierwrite is submitted?
A private concurrent queue: reads via sync run in parallel, the write via async(flags: .barrier) runs exclusively.
final class Cache {
private var storage: [String: Data] = [:]
private let queue = DispatchQueue(label: "cache", attributes: .concurrent)
func value(for key: String) -> Data? {
queue.sync { storage[key] } // concurrent reads
}
func set(_ value: Data, for key: String) {
queue.async(flags: .barrier) { // exclusive write
self.storage[key] = value
}
}
}
Without .barrier, an async write on a concurrent queue would overlap in-flight reads — a data race. The barrier waits for current reads to finish, runs alone, and only then lets new reads proceed.