Расставляем точки над всеми буквами по поводу многопоточности и асинхронности.
Эти два понятия часто путают, но они решают разные проблемы.
Что есть многопоточность: разделение логики приложения на выполнение в физически разные потоки. Данный механизм помогает нам распределить нагрузку равномерно между всеми ядрами системы. Даёт профит только тогда, когда речь идёт о алгоритмах, жадных до процессорного времени. Как пример сложные математические расчёты: рендер изобраений, расчёт хэшей (привет, крипта!), перекодирование видео, расчёт физических (или химических) явлений и процессов, и прочая инженерная хрень. Как работает: берём алгоритм, отдаём ему какую-то задачу и он в отдельном треде решает её от начала и до победы, не прерываясь на перекуры.
Асинхронность же всего лишь способность разбить процесс выполнения задачи на этапы, отпускающие поток выполнения в моменты простоя. Даёт профит только на задачах с повышенной нагрузкой на IO (ввод-вывод). Тут примером могут быть обращения к БД, сетевые запросы, работа с файловой системой или внешними устройствами. Как работает: берём задачу, например запрос к rest серверу, и отдаём исполнителю (executor), который выполняет запрос к серверу, после чего натыкается на что-то вроде await
или wait
и паркует задачу (или ложит её на стек) и идёт выполнять следующую аналогичную задачу, возвращаясь к первой только когда она получит ответ от сервера и оповестит об этом исполнителя.