Ответ
Sync/Async и Serial/Concurrent — это ортогональные характеристики в Grand Central Dispatch.
1. Тип очереди (качество):
- Serial (последовательная): Задачи выполняются строго одна за другой (FIFO).
- Concurrent (параллельная): Задачи могут выполняться одновременно на нескольких потоках.
2. Способ отправки задачи (модальность):
- Sync (синхронно): Блокирует текущий поток до полного выполнения задачи.
- Async (асинхронно): Отправляет задачу и немедленно продолжает выполнение в текущем потоке.
Примеры:
let serialQueue = DispatchQueue(label: "com.example.serial")
let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
// Serial + Async: Порядок гарантирован, текущий поток не блокируется
serialQueue.async { print("Task 1") }
serialQueue.async { print("Task 2") } // Начнется только после Task 1
// Concurrent + Async: Порядок не гарантирован, задачи могут выполняться параллельно
concurrentQueue.async { print("Task A") }
concurrentQueue.async { print("Task B") } // Может начаться до завершения Task A
// Sync (опасно!): Блокирует текущий поток. Может привести к deadlock на serial очереди.
serialQueue.sync {
print("Это выполнится, но поток будет ждать")
// serialQueue.sync { ... } // DEADLOCK! Очередь ждет сама себя.
}
Основное правило: Используйте async по умолчанию. Sync применяйте осторожно, в основном для синхронизации доступа к общим данным или когда следующий код зависит от результата задачи.