Default
Если корутина не находит в своем контексте диспетчер, то она использует диспетчер по умолчанию. Этот диспетчер представляет собой пул потоков. Количество потоков равно количеству ядер процессора.
Он не подходит для IO операций, но сгодится для интенсивных вычислений.
IO
Использует тот же пул потоков, что и диспетчер по умолчанию. Но его лимит на потоки равен 64 (или числу ядер процессора, если их больше 64).
Этот диспетчер подходит для выполнения IO операций (запросы в сеть, чтение с диска и т.п.).
Main
Main диспетчер запустит корутину в основном потоке. Не забываем что корутина не заблокирует поток а приостановит выполнение кода. В корутине, которая выполняется в Main потоке, мы можем спокойно писать обычный (типичный для Activity или фрагментов) код, который работает с UI. Но при этом мы можем в этом же коде вызывать suspend функции, которые будут асинхронно получать данные с сервера или БД. И нам не нужны будут колбэки и переключения потоков. Все это скрыто под капотом корутин, а наш код выглядит чище и лаконичнее.
Unconfined
У диспетчера Unconfined метод isDispatchNeeded возвращает false. Это приводит к тому, что при старте и возобновлении выполнения кода Continuation не происходит смены потока.
Т.е. при старте корутина выполняется в том потоке, где был вызван билдер, который эту корутину создал и запустил. А при возобновлении выполнения из suspend-функции, корутина выполняется в потоке, который использовался в suspend-функции для выполнения фоновой работы. Ведь именно в этом потоке мы вызываем continuation.resume.