Ответ
Разница заключается в порядке выполнения задач и использовании потоков.
| Характеристика | Serial Queue (Последовательная) | Concurrent Queue (Параллельная) |
|---|---|---|
| Выполнение задач | Строго по порядку, одна за другой. | Одновременно, насколько позволяет система. |
| Потоки | Использует один поток (но не обязательно всегда один и тот же системный поток). | Использует несколько потоков из пула. |
| Главное преимущество | Гарантированная потокобезопасность для общих ресурсов. | Производительность за счёт параллелизма. |
| Типичное применение | Синхронизация доступа к общим данным, порядок операций. | Выполнение независимых, ресурсоёмких задач. |
Практический пример:
let serialQueue = DispatchQueue(label: "com.example.serial")
let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
// Задачи на Serial Queue выполнятся суммарно за ~3 секунды.
serialQueue.async { sleep(1); print("Serial Task 1 done") }
serialQueue.async { sleep(1); print("Serial Task 2 done") } // Ждёт окончания Task 1
serialQueue.async { sleep(1); print("Serial Task 3 done") } // Ждёт окончания Task 2
// Задачи на Concurrent Queue выполнятся суммарно за ~1 секунду.
concurrentQueue.async { sleep(1); print("Concurrent Task 1 done") }
concurrentQueue.async { sleep(1); print("Concurrent Task 2 done") } // Запускается сразу
concurrentQueue.async { sleep(1); print("Concurrent Task 3 done") } // Запускается сразу
Ключевой вывод:
- Быстрее для независимых задач — concurrent очередь.
- Безопаснее для операций с общим состоянием — serial очередь (или concurrent с барьерами
.barrier). Выбор зависит от конкретной задачи.