Что такое барьерная задача (dispatch barrier) в GCD?

«Что такое барьерная задача (dispatch barrier) в GCD?» — вопрос из категории Многопоточность, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Барьерная задача (Dispatch Barrier) — это специальный тип задачи в Grand Central Dispatch (GCD), которая при добавлении в concurrent очередь заставляет очередь выполнить её эксклюзивно относительно всех других задач в этой же очереди.

Принцип работы:

  1. Все задачи, добавленные в очередь до барьерной, выполняются как обычно (параллельно, если очередь concurrent).
  2. Когда наступает очередь барьерной задачи, очередь приостанавливается и выполняет только её, пока та не завершится.
  3. После завершения барьерной задачи очередь возобновляет параллельное выполнение задач, добавленных после неё.

Типичный use-case: Реализация потокобезопасного кэша или структуры данных с паттерном "множество читателей, один писатель" (Multiple Readers, Single Writer).

Пример: Потокобезопасный кэш с использованием барьера

class ThreadSafeCache<Key: Hashable, Value> {
    private let concurrentQueue = DispatchQueue(
        label: "com.example.cacheQueue",
        attributes: .concurrent // 1. Очередь ДОЛЖНА быть concurrent
    )
    private var storage: [Key: Value] = [:]

    // ЧТЕНИЕ: может выполняться параллельно многими потоками
    func getValue(for key: Key) -> Value? {
        concurrentQueue.sync {
            storage[key]
        }
    }

    // ЗАПИСЬ: выполняется эксклюзивно благодаря барьеру
    func setValue(_ value: Value, for key: Key) {
        concurrentQueue.async(flags: .barrier) { // 2. Флаг .barrier
            storage[key] = value
        }
    }
}

Важные ограничения:

  • Барьер работает только с concurrent очередями, созданными вручную (с атрибутом .concurrent).
  • Не работает с глобальными очередями (DispatchQueue.global()), главной очередью (DispatchQueue.main) или последовательными (serial) очередями.
  • В Swift Concurrency аналогичная семантика достигается с помощью акторов (actor), которые обеспечивают эксклюзивный доступ к своим данным.