안녕하세요. 이번에는 GlobalScope와 CoroutineScope의 차이점에 대해 알아보겠습니다.
포스팅에 앞서, CoroutineContext에 대해 어느정도 이해를 가지고 보시는 것을 추천드립니다.
먼저, GlobalScope와 CoroutineScope()의 코드를 한번 보겠습니다.
public object GlobalScope : CoroutineScope {
/**
* Returns [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
public fun CoroutineScope(context: CoroutineContext): CoroutineScope =
ContextScope(if (context[Job] != null) context else context + Job())
GlobalScope는 EmptyCoroutineContext를 CoroutineContext로 사용하고 있고, CoroutineScope()는 CoroutineContext가 강제되고, 넘겨 받은 CoroutineContext에 Job이 없으면 추가해주는 것을 볼 수 있습니다.
public object EmptyCoroutineContext : CoroutineContext, Serializable {
private const val serialVersionUID: Long = 0
private fun readResolve(): Any = EmptyCoroutineContext
public override fun <E : Element> get(key: Key<E>): E? = null
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R = initial
public override fun plus(context: CoroutineContext): CoroutineContext = context
public override fun minusKey(key: Key<*>): CoroutineContext = this
public override fun hashCode(): Int = 0
public override fun toString(): String = "EmptyCoroutineContext"
}
internal class ContextScope(context: CoroutineContext) : CoroutineScope {
override val coroutineContext: CoroutineContext = context
// CoroutineScope is used intentionally for user-friendly representation
override fun toString(): String = "CoroutineScope(coroutineContext=$coroutineContext)"
}
readResolve() 함수에 대해서는 [Kotlin] Signleton Serialization 을 보시면 됩니다.
간략하게는, Signleton Object가 재생성이 되는 것을 방지하는 함수입니다.
EmptryCoroutineContext를 보면 CoroutineContext의 Element가 아무것도 없는 것을 볼 수 있습니다.
반면에, ContextScope는 파라미터로 넘겨받은 CoroutineContext를 사용하는 것을 볼 수 있죠.
여기서, GlobalScope와 CoroutineScope()는 GlobalScope가 Signleton인 점, CoroutineContext의 Element 유무 말고는 차이점이 없는 것을 볼 수 있습니다.
먼저, GlobalScope가 Signleton이기 때문에 생기는 차이점에 대해 알아보겠습니다.
다음으로, CoroutineContext의 유무 때문에 생기는 차이점에 대해 알아보겠습니다.