Ответ
Барьер (Dispatch Barrier) — это задача в Grand Central Dispatch (GCD), которая при выполнении на concurrent очереди действует как точка синхронизации, обеспечивая эксклюзивный доступ.
Принцип работы:
На concurrent очереди (attributes: .concurrent):
- Задачи, поставленные до барьерной задачи, выполняются параллельно.
- Барьерная задача ждет завершения всех предыдущих задач, а затем выполняется в одиночку (очередь временно становится serial).
- Задачи, поставленные после барьера, ждут его завершения, а затем снова выполняются параллельно.
Пример использования для потокобезопасного кэша:
class ThreadSafeCache<Key: Hashable, Value> {
private var cache: [Key: Value] = [:]
// Важно: очередь ДОЛЖНА быть concurrent
private let queue = DispatchQueue(label: "com.app.cacheQueue", attributes: .concurrent)
func getValue(for key: Key) -> Value? {
// Множественные чтения могут выполняться параллельно
return queue.sync { cache[key] }
}
func setValue(_ value: Value, for key: Key) {
// Запись выполняется эксклюзивно через барьер
queue.async(flags: .barrier) {
self.cache[key] = value
}
}
}
Строгие правила и предупреждения:
- Только для concurrent очередей: На serial очередях или глобальных очередях (
DispatchQueue.global()) барьер ведет себя как обычная задача, не давая гарантий эксклюзивности. - Цель — читатели-писатели: Идеальная абстракция для паттерна «Multiple Readers, Single Writer».
- Асинхронность: Барьерные задачи обычно добавляются асинхронно (
async), чтобы не блокировать вызывающий поток.
Итог: Барьер — это мощный инструмент GCD для организации безопасного доступа к общему ресурсу из нескольких потоков на concurrent очереди.