
Kotlin【입문-Coroutine①-】
개요
kotlin coroutine에 대해 잡아 보았습니다.
참고 자료:
Coroutine Basics
Cancellation and Timeouts
Composing Suspending Functions
기본 시스템
GlobalScope.launch
에서 코 루틴 시작 (1 초 중지) main.kt
import kotlinx.coroutines.*
fun main() {
GlobalScope.launch {
delay(1000L) // コルーチンで1秒停止
println("World!")
}
println("Hello,")
Thread.sleep(2000L) // メインスレッドで2秒停止
}
포인트
GlobalScope.launch
로 시작합니다.Blocking(블로킹)
main.kt
fun main() {
GlobalScope.launch {
delay(1000L) // コルーチンで1秒停止 non-blocking
println("World!")
}
println("Hello,")
runBlocking {
delay(2000L) // メインスレッドを2秒停止
}
}
// 以下のようにすることでも同じ結果を得られる
fun main() = runBlocking {
GlobalScope.launch {
delay(1000L) // コルーチンで1秒停止 non-blocking
println("World!")
}
println("Hello,")
delay(2000L)
}
// runBlockingを用いることでコルーチンが終了するまで、アプリケーションの終了を待つことができる
fun main() = runBlocking {
val job = GlobalScope.launch {
delay(1000L)
println("World!")
}
println("Hello,")
job.join()
}
// `GlobalScope.launch`ではなく`launch`を用いることでこのスコープ内でコルーチンを起動する
fun main() = runBlocking {
launch {
delay(1000L)
println("World!")
}
println("Hello,")
}
포인트
runBlocking {...}
를 사용하면 내부 코루틴이 끝날 때까지 스레드를 차단 (중지) 할 수 있습니다.GlobalScope.launch
및 launch
로 시작할 범위를 지정할 수 있습니다.coroutineScope(스코프)
main.kt
fun main() = runBlocking {
// 処理が完了するまでスレッドを停止する
launch {
delay(200L)
println("Task from runBlocking")
}
coroutineScope {
launch {
delay(500L)
println("Task from nested launch")
}
delay(100L)
println("Task from coroutine scope")
}
println("Coroutine scope is over")
}
포인트
GlobalScope.launch
및 launch
로 시작할 범위를 지정할 수 있습니다.Cancel(취소)
main.kt
fun main() = runBlocking {
val job = launch {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L)
println("main: I'm tired of waiting!")
job.cancel() // jobのキャンセル
job.join() // job完了を待つ
println("main: Now I can quit.")
}
fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
// 以下のコルーチンはキャンセルされないようにする
withContext(NonCancellable) {
println("job: I'm running finally")
delay(1000L)
println("job: And I've just delayed for 1 sec because I'm non-cancellable")
}
}
}
delay(1300L)
println("main: I'm tired of waiting!")
job.cancelAndJoin() // jobのキャンセル&完了を待つ
println("main: Now I can quit.")
}
포인트
cancel
메소드에서 job (코 루틴)을 취소 할 수 있습니다 join
에서 job (코루틴)의 끝까지 기다린다 cancelAndJoin
라는 cancel과 join이 합쳐진 메소드도 있다 try {...} finally {...}
를 사용하여 취소하면 finally
블록을 통과합니다. withContext(NonCancellable) {...}
를 사용하여 취소되지 않도록 할 수 있습니다.Timeout(타임아웃)
main.kt
fun main() = runBlocking {
withTimeout(1300L) {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
}
fun main() = runBlocking {
val result = withTimeoutOrNull(1300L) {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
"Done" // will get cancelled before it produces this result
}
println("Result is $result")
}
포인트
withTimeout
에서 job (코 루틴) 제한 시간을 설정할 수 있습니다 (타임 아웃시 예외를 throw합니다.)withTimeoutOrNull
는 타임 아웃시에 null를 돌려줍니다 Suspend 함수
main.kt
fun main() = runBlocking {
launch { doWorld() }
println("Hello,")
}
// this is your first suspending function
suspend fun doWorld() {
delay(1000L)
println("World!")
}
main.kt
suspend fun doSomethingUsefulOne(): Int {
delay(1000L)
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L)
return 29
}
// The answer is 42
// Completed in 2017 ms
fun 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")
}
// The answer is 42
// Completed in 1017 ms
fun 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")
}
포인트
delay
마지막으로
알사가 파트너스 Advent Calendar 2020 22일째는 @miumi 님의 턴입니다.
