September 29, 2020
fun main() = runBlocking {
//    예제1
//      서로 의존성있는 메소드일 때
//      코루틴 내부에서 중단메소드를 활용하면 꿈의 코드처럼 순차적으로 작동된다.
    var one = 0
    var two = 0
    val time = measureTimeMillis {
        one = doSomethingUsefulOne() // 첫번째 중단
        two = doSomethingUsefulTwo(one) // 두번째 중단
        println("The answer is ${one+two}")
    }
    println("Completed in $time ms")
}
suspend fun doSomethingUsefulTwo(_one : Int): Int {
    delay(1000)
    return _one+13
}
suspend fun doSomethingUsefulOne(): Int {
    delay(1000)
    return 29
}
// The answer is 71
// Completed in 2010 msfun main() = runBlocking {
   val time = measureTimeMillis {
        val one = async { doSomethingUsefulOne() } // 첫번째 중단
        val two = async { doSomethingUsefulTwo() } // 두번째 중단
        println("The answer is ${one.await()+two.await()}")
    }
    println("Completed in $time ms")
}
suspend fun doSomethingUsefulTwo(): Int {
    delay(1000)
    return 13
}
suspend fun doSomethingUsefulOne(): Int {
    delay(1000)
    return 29
}
// The answer is 42
// Completed in 1026 msfun main() = runBlocking {
    val time = measureTimeMillis {
        val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() } // 첫번째 중단
        val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() } // 두번째 중단
        one.start()
        two.start()
        println("The answer is ${one.await()+two.await()}")
    }
    println("Completed in $time ms")
}
suspend fun doSomethingUsefulTwo(): Int {
    delay(1000)
    return 13
}
suspend fun doSomethingUsefulOne(): Int {
    delay(1000)
    return 29
}
// The answer is 42
// Completed in 1017 msfun main() = runBlocking<Unit> {
   try {
       failedConcurrentSum()
   } catch (e : ArithmeticException) {
       println("Computation failed with ArithmetickException")
   }
}
suspend fun failedConcurrentSum() : Int = coroutineScope {
   val one = async {
       try {
           delay(Long.MAX_VALUE)
           42
       } finally {
           println("First child was cancelled")
       }
   }
   val two = async<Int> {
       println("Second child throws an exception")
       throw ArithmeticException()
   }
   one.await() + two.await()
}
// Second child throws an exception
// First child was cancelled
// Computation failed with ArithmetickException