val someCoroutineContext = someJob + Dispatchers.IO + someCoroutineName + someExceptionHandler
코루틴에 이름을 주며, 디버깅을 위해 사용됨.
val someCoroutineName = CoroutineName("someCoroutineName")
작업 객체를 지정할 수 있으며, 취소 가능 여부에 따라 SupervisorJob()을 사용함.
val parentJob = SupervisorJob() // 자식에서 취소되더라도 부모와 다른 자식에 영향 X
val someJob = Job(parentJob)
Dispatchers.Default, ...IO 등을 지정할 수 있으며, 필요에 따라 스레드풀 생성 가능
val myPool = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
val someExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
val coroutineName = coroutineContext[CoroutineName]?.name ?: "default coroutine name"
println("Error in $coroutineName: ${throwable.localizedMessage}")
}
val scope1 = GlobalScope
scope1.launch { ... }
scope1.async { ... }
or
GlobalScope.launch { ... }
val job1 = GlobalScope.launch { ... } // Job 객체 -> Job.join()으로 대기
val job2 = GlobalScope.async { ... } // Deferred 객체 -> Deferred.await()으로 대기 (실행 결과 반환)
val scope2 = CoroutineScope(Dispatchers.Default)
val routine1 = scope2.launch { ... }
val routine2 = scope2.async { ... }
or
launch(Dispatchers.Default) { ... }
async(Dispatchers.Default) { ... }
package chap06.section2
import kotlinx.coroutines.*
// 메인 함수 자체가 코루틴 스코프
fun main() = runBlocking {
launch {
delay(1200L)
println("Task from runBlocking") // 4
}
coroutineScope {
launch {
delay(200L)
println("Task from nested launch") // 2
}
delay(200L)
println("Task from coroutineScope") // 1
}
println("end of runBlocking") // 3
}
Task from coroutineScope
Task from nested launch
end of runBlocking
Task from runBlocking
package chap06.section2
import kotlinx.coroutines.*
// 메인 함수 자체가 코루틴 스코프가 되도록
fun main() = runBlocking {
launch {
delay(1200L)
println("Task from runBlocking") // 2
}
coroutineScope {
launch {
delay(1500L)
println("Task from nested launch") // 3
}
delay(200L)
println("Task from coroutineScope") // 1
}
println("end of runBlocking") // 4
}
Task from coroutineScope
Task from runBlocking
Task from nested launch
end of runBlocking
package chap06.section2
import kotlinx.coroutines.*
fun main() = runBlocking(Dispatchers.Default) {
launch(Dispatchers.IO) {
delay(1200L)
println("Task from runBlocking") // 2
}
coroutineScope {
launch {
delay(1500L)
println("Task from nested launch") // 3
}
delay(200L)
println("Task from coroutineScope") // 1
}
println("end of runBlocking") // 4
}
위의 코드처럼 runBlocking, launch의 Context 인자에 특정 디스패처를 지정해줄 수도 있다.
val threadPool = Executors.newFixedThreadPool(4) // 스레드 개수 직접 지정하는 경우
val myContext = threadPool.asCoroutineDispatcher()
...
async(myContext) { ... }