Kotlin
                
              Kotlin - Coroutine cancel
                jinhan38
                 2021. 4. 10. 02:29
              
                          
                    runBlocking {
            //    Dispatchers.Default 는 코루틴이 GlobalScope 에서 실행될 경우에
            //    사용되며 공통으로 사용되는 백그라운드 스레드 풀을 이용합니다.
            //    즉, launch(Dispatchers.Default) {…} 와 GlobalScope.launch {…} 는
            //    동일한 디스패처를 사용합니다.
            //코루틴을 cancel시키기 위해서는 suspend function call 이 필요함
            //yield와 delay()가 suspend function 역할을 함
            val startTime = System.currentTimeMillis()
            val job = launch(Dispatchers.Default) {
                try {
                    var nextPrintTime = startTime
                    var i = 0
                    while (i < 5) {
                        if (System.currentTimeMillis() >= nextPrintTime) {
                            yield()
                            println("aaaaaaaaaaa : ${i++}  aaaaaaaaaa")
                            nextPrintTime += 500
                        }
                    }
                } catch (e: Exception) {
                    println("Exception : $e")
                }
            }
            delay(2000)
            job.cancelAndJoin()    // cancel을 시키면 yield가 exception을 던진다
        }
class KotlinPlayGroundActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin_play_ground)
        // launch로 코루틴을 실행했을 때는 yield나 delay를 넣어서 cancel을 호출하여 exception을 던져야 한다.
        // exception 없이 cancel하기 위해서는  Dispatchers.Default와 isActive를 이용해서 하면 된다. 
        runBlocking {
            val startTime = System.currentTimeMillis()
            val job = launch(Dispatchers.Default) {
                var nextPrintTime = startTime
                var i = 0
                printlnThreadName("isActive : $isActive ~~~~~~~~")
                while (isActive) {
                    if (System.currentTimeMillis() >= nextPrintTime) {
                        printlnThreadName("aaaaaaaaaaa : ${i++}  aaaaaaaaaa")
                        nextPrintTime += 500
                    }
                }
                printlnThreadName("isActive : $isActive ~~~~")
            }
            delay(2000)
            job.cancelAndJoin()
        }
    }
    fun printlnThreadName(msg: String) {
        println("$msg, current thread : ${Thread.currentThread().name}")
    }
}