코루틴을 중단한다는 것은 실행을 중간에 멈추는 것을 의미합니다.

코루틴은 중단되었을 때, Continuation 객체를 반환합니다. **Continuation**을 이용하면 멈췄던 곳에서 다시 코루틴을 시작할 수 있습니다.

코루틴이 중단되었을 때, 코루틴은 어떤 자원도 사용하지 않습니다. 언제든지 다른 스레드에서 시작될 수 있고, Continuation 객체는 직렬화와 역직렬화가 가능하며 다시 실행될 수 있습니다.

재개

코루틴이 중단된 후, 작업이 재개되는 원리를 알아봅니다.

중단 함수는 반드시 코루틴 또는 다른 중단 함수에 의해 호출되어야 합니다.

“Before”와 “After” 사이에서 중단하면, “After”은 출력되지 않으며 main 함수가 끝나지 않았기 때문에 코드는 실행된 상태로 유지됩니다.

suspend fun main() {
    println("Before")

    suspendCoroutine<Unit> {  }

    println("After")
}

// Before

코루틴을 다시 실행시키려면 **Continuation**을 이용해야 합니다. **Continuation**은 suspendCoroutine의 인자로 들어간 람다 함수의 인자로 제공됩니다.

Continuation 객체를 이용해 코루틴을 중단한 후 실행할 수 있습니다.

suspend fun main() {
    println("Before")

    suspendCoroutine<Unit> { continuation ->
        continuation.resume(Unit)
    }

    println("After")
}

// Before
// After

suspendCoroutine에서 잠깐 동안 sleep된 뒤 재개되는 다른 스레드를 실행할 수 있습니다.

suspend fun main() {
    println("Before")

    suspendCoroutine { continuation ->
        thread { 
            Thread.sleep(1000)
            continuation.resume(Unit)
        }
    }

    println("After")
}

다만, 위와 같은 방식은 비용이 많이 들기에 ScheduledExecutorService를 사용할 수 있습니다.

suspend fun main() {
    println("Before")

    suspendCoroutine { continuation ->
        executor.schedule(
            {
                println("ScheduledExecutorService")
                continuation.resume(Unit)
            },
            1000,
            TimeUnit.SECONDS
        )
    }

    println("After")
}