Что делает Thread#join в Ruby?

Ожидание завершения потока, результат join, тайм-аут и получение значения через Thread#value.

Короткий ответ

Что ответить на собеседовании

thread.join приостанавливает вызывающий поток до завершения thread. При нормальном завершении возвращается объект Thread, а при истечении переданного тайм-аута — nil, не false. Тайм-аут прекращает ожидание, но не отменяет работу потока. Необработанное исключение дочернего потока может быть повторно выброшено при join. Для результата блока используется thread.value.

Подробный разбор

Ответ с пояснениями

join — ожидание завершения другого потока. Он не запускает поток впервые: Thread.new уже создаёт и запускает работу, а join задаёт точку, после которой вызывающий код может рассчитывать на её завершение.

worker = Thread.new do
  sleep 0.1
  6 * 7
end

worker.join
p worker.value # 42

Сам join при нормальном завершении возвращает объект worker, а не число 42. value тоже ждёт завершения при необходимости и возвращает результат блока.

Можно ограничить время ожидания в секундах:

worker = Thread.new { sleep 0.1; :done }

if worker.join(0.01).nil?
  puts "Пока не завершён"
end

worker.join # В примере явно дожидаемся оставшейся работы

При тайм-ауте результат — nil, а поток продолжает выполняться. Между возвратом по тайм-ауту и следующей строкой он уже может успеть завершиться, поэтому сообщение означает лишь результат данного ожидания. В приложении отдельно продумывают отмену или повторное ожидание.

Если работа завершилась необработанным исключением, оно распространяется в поток, который выполняет join или value. Обработчик ошибок должен учитывать этот сценарий. Ожидание всех задач не заменяет защиту общего изменяемого состояния во время их работы: для этого нужны подходящие средства синхронизации. Thread#join, Thread#value.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку