← Назад к вопросам

В чем разница между очередью Async и Concurrent?

2.2 Middle🔥 181 комментариев
#Многопоточность и асинхронность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между Async и Concurrent очередями в GCD

Async vs Sync

Async и Sync — это не очереди, а способы добавления задач в очередь.

Async (асинхронный):

DispatchQueue.global().async {
    // Код выполнится позже
    // Функция вернёт управление сразу
    print("Async: выполнится в фоне")
}
print("После async")
// Вывод: После async → Async: выполнится в фоне

Sync (синхронный):

DispatchQueue.global().sync {
    // Код выполнится сейчас
    // Функция ждёт завершения
    print("Sync: выполнится сейчас")
}
print("После sync")
// Вывод: Sync: выполнится сейчас → После sync

Serial Queue (последовательная очередь)

Serial Queue — выполняет задачи одну за другой:

let serialQueue = DispatchQueue(label: "com.example.serial")

serialQueue.async { print("Task 1") }  // Выполнится 1-й
serialQueue.async { print("Task 2") }  // Выполнится 2-й
serialQueue.async { print("Task 3") }  // Выполнится 3-й

// Вывод: Task 1 → Task 2 → Task 3

Гарантирует порядок!

Concurrent Queue (параллельная очередь)

Concurrent Queue — выполняет задачи одновременно:

let concurrentQueue = DispatchQueue(
    label: "com.example.concurrent",
    attributes: .concurrent
)

concurrentQueue.async { print("Task 1") }  // Может выполниться в любом порядке
concurrentQueue.async { print("Task 2") }  
concurrentQueue.async { print("Task 3") }  

// Вывод: Task 1 → Task 3 → Task 2 (случайный порядок)

Не гарантирует порядок!

Сравнительная таблица

SerialConcurrent
ПорядокГарантированНе гарантирован
ПараллелизмНет (одна задача)Да (несколько задач)
Потоки1 потокНесколько потоков
ПроизводительностьМедленнееБыстрее
СинхронизацияВстроенаНужна вручную

Global Queue (встроенная concurrent)

DispatchQueue.global().async {  // Встроенная concurrent queue
    // Может выполняться параллельно с другим кодом
}

Практический пример

Serial Queue для синхронизации:

class DataManager {
    private let dataQueue = DispatchQueue(label: "com.example.data")
    private var data: [String] = []
    
    func addData(_ item: String) {
        dataQueue.async {  // Serial = безопасно
            self.data.append(item)
        }
    }
    
    func getData() -> [String] {
        var result: [String] = []
        dataQueue.sync {  // Ждём завершения
            result = self.data
        }
        return result
    }
}

Concurrent Queue для параллельных операций:

let concurrentQueue = DispatchQueue(
    label: "com.example.processing",
    attributes: .concurrent
)

for item in items {
    concurrentQueue.async {  // Все параллельно
        process(item)
    }
}

Когда использовать

Serial Queue: ✅ Синхронизация доступа к ресурсам ✅ Когда нужен гарантированный порядок ✅ Database access ✅ Singleton управление

Concurrent Queue: ✅ Параллельная обработка ✅ Когда порядок не важен ✅ Bulk операции ✅ Network запросы

Барьер в Concurrent Queue

let concurrentQueue = DispatchQueue(
    label: "com.example.concurrent",
    attributes: .concurrent
)

concurrentQueue.async { print("Read 1") }
concurrentQueue.async { print("Read 2") }

// Барьер: ждёт завершения всех, затем выполняет
concurrentQueue.async(flags: .barrier) {
    print("Write (exclusive)")  // Одна задача
}

concurrentQueue.async { print("Read 3") }

Ключевые правила

✅ Async — добавить задачу, вернуть управление ✅ Sync — ждать завершения задачи ✅ Serial — одна задача, гарантированный порядок ✅ Concurrent — несколько задач одновременно ❌ Никогда sync в главный поток из главного потока ❌ Не используй sync для долгих операций

Правильный выбор queue типа критичен для производительности и безопасности потоков.