Как запустить поток в Java/Kotlin и какой интерфейс реализуется для передачи исполняемого кода
Что проверяют
Базу многопоточности: разницу между start() и run(), между Runnable и Callable, и понимание, что происходит с UI-потоком на Android. Следом спрашивают, как вернуть результат из фона на экран и почему голые потоки в современном коде почти не пишут.
Как отвечать
Runnable: функциональный интерфейс с методомvoid run(), без результата и без checked-исключений. Передаётся в конструкторThread, в Java этоnew Thread(() -> work()).start();Callable<V>: методcall()возвращает значение и может бросать исключение. Запускается черезExecutorService.submit(), результат приходит вFuture<V>, аget()блокирует до готовности;- Kotlin: благодаря SAM-преобразованию пишется
Thread { work() }.start(), а функцияthread { }изkotlin.concurrentсразу создаёт и запускает поток; start()противrun(): новый поток создаёт толькоstart(). Прямой вызовrun()выполнит код в текущем потоке. Повторныйstart()бросаетIllegalThreadStateException;- пулы:
Executors.newFixedThreadPool()переиспользует потоки и ограничивает их число.
Дальше про Android. Сеть в главном потоке запрещена (NetworkOnMainThreadException), а трогать view из фонового нельзя (CalledFromWrongThreadException). Результат возвращают через Handler(Looper.getMainLooper()).post { }, runOnUiThread или view.post. Необработанное исключение в любом потоке роняет всё приложение.
Закончите тем, как пишут сейчас: корутины с Dispatchers.IO в viewModelScope, а для работы, которая должна пережить закрытие приложения, WorkManager. AsyncTask объявлен устаревшим в API 30.
Где спотыкаются
Вызывают run() вместо start() и уверены, что код ушёл в фон. На деле он блокирует главный поток, и при долгой работе ловится ANR.
Держат в Runnable ссылку на Activity. Поток живёт дольше экрана, после поворота старая Activity не собирается сборщиком мусора, получается утечка.
Называют корутины лёгкими потоками и ставят знак равенства с Thread. Корутина выполняется на потоках диспетчера и после точки приостановки может продолжиться уже на другом.