- Закрепить на практике работу с корутинами.
- Создать приостанавливаемые функции.
- Научиться запускать и прерывать исполнение корутин.
Напишите программу, которая вычисляет n-е число из ряда Фибоначчи. Вы уже сталкивались с задачей о числах Фибоначчи при изучении циклов. Теперь вам необходимо доработать существующий код или написать программу заново с использованием корутин.
-
Создайте объект-синглтон Fibonacci.
-
В этом объекте создайте suspend функцию
take
. Функция принимает на вход число — номер в последовательности Фибоначчи — и возвращает рассчитанное число типаBigInteger
. Для создания числаBigInteger
используйте функцию-расширениеtoBigInteger
. -
Запустите две или более корутин в функции main. Используйте для этого функцию
runBlocking
и билдерlaunch
. Внутри каждой корутины вызовите функциюtake
и выведите результат в консоль. -
Рассчитайте несколько чисел Фибоначчи в порядке возрастания, затем в порядке убывания. Запустите программу несколько раз и проанализируйте порядок работы корутин.
Например: По возрастанию:
launch { take(5) }
launch { take(10) }
launch { take(15) }
- Сделайте suspend функцию
take
отменяемой. Используйте для этого функциюyield
. Или функциюcurrentCoroutineContext
и его расширениеisActive
.
Например:
currentCoroutineContext().isActive
При необходимости выполнение функции должно прерываться. Точки прерывания определите самостоятельно, исходя из реализации вашей функции.
-
Запустите программу ещё несколько раз и вновь проанализируйте порядок работы корутин.
-
Отмените выполнение функции
take
при превышении какого-то времени. Используйте для этого функциюwithTimeout
.
Например:
withTimeout(3000) {
// some code
}
-
Запускает блок кода на выполнение и прерывает его выполнение при превышении 3-х секунд.
Числа в цикле рассчитываются быстро, поэтому, чтобы отмена по таймауту была заметна, необходимо рассчитывать числа из последовательности Фибоначчи с довольно большим порядковым номером. Использование цикла вместо рекурсии и
BigInteger
вместоLong
избавит от переполнения типа данных и переполнения стека.
-
При отмене по таймауту выбрасывается исключение
TimeoutCancellationException
. Обработайте это исключение и выведите в консоль сообщение о превышении времени вычисления. -
Запустите ещё одну корутину, которая будет индикатором вычислений и выведет точки в консоль. Эта корутина должна работать до тех пор, пока идут вычисления всех ваших чисел Фибоначчи.
- По желанию: Добейтесь, чтобы вывод рассчитанных значений происходил после того, как будут рассчитаны все числа. Тем самым числа будут рассчитываться параллельно, но индикатор прогресса (точки) не будет прерываться сообщениями о рассчитанном числе.
Можно использовать для этого Job
и функцию join
.