CoroutineScope
를 활용한 적 있다.fun main(): Unit = runBlocking {
val job1 = CoroutineScope(Dispatchers.Default).launch {
delay(1_000L)
printWithThread("Job 1")
}
}
launch
와 async
는 사실 CoroutineScope
의 확장함수이다.runBlocking
이 코루틴과 루틴 세계를 이어주며 CoroutineScope
를 제공해준 것이다.
CoroutineScope
를 만들면 runBlocking
은 필요하지 않다.fun main() {
val job = CoroutineScope(Dispatchers.Default).launch {
delay(1_000L)
printWithThread("Job 1")
}
Thread.sleep(1_500L) // job이 새 스레드에서 루트 코루틴으로 실행되기에 기다려야 Job1이 출력될 것이다.
}
CoroutineScope
는 코루틴이 탄생할 수 있는 영역이다.
CoroutineScope
는 CoroutineContext
데이터 보관한다.CoroutineContext
는 코루틴과 관련된 데이터를 보관
CoroutineExceptionHandler
, 코루틴 이름, 코루틴 그 자체, CoroutineDispatcher
등Dispatcher
는 코루틴이 어떤 스레드에 배정될지 관리한다.public interface CoroutineScope {
public val coroutineContext: CoroutineContext
}
CoroutineScope
에서 생성된다.context
에서 필요한 정보를 덮어 써 새로운 자신의 context
를 만든다.
class AsyncLogic {
private val scope = CoroutineScope(Dispatchers.Default)
fun doSomething() {
scope.launch {
// 어떤 작업을 수행
}
}
fun destroy() {
scope.cancel()
}
}
val asyncLogic = AsyncLogic()
asyncLogic.doSomething()
asyncLogic.destory() // 필요 없어지면 모두 정리
Map
+ Set
을 합쳐놓은 상태
+
기호를 이용해 Element들을 합칠 수도 있다.fun main() {
// 각각이 Element이다.
CoroutineName("나만의 코루틴") + Dispatchers.Default
// context 자체에 Element를 추가할 수도 있다.
coroutineContext + CoroutineName("나만의 코루틴")
// Element를 제거할 수도 있다.
coroutineContext.minusKey(CoroutineName.key)
}
Dispatchers.Default
Dispatchers.IO
Dispatchers.Main
ExecutorService
를 디스패처로 변환
asCoroutineDispatcher
확장 함수 사용fun main() {
val threadPool = Executors.newSingleThreadExecutor()
CoroutineScope(threadPool.asCoroutineDispatcher()).launch {
printwithThread("새로운 코루틴")
}
}