Why not use GlobalScope.launch?

前端 未结 3 1576
-上瘾入骨i
-上瘾入骨i 2020-12-01 10:45

I read that usage of Globalscope is highly discouraged, here.

I have a simple use-case. For every kafka message (let\'s say a list of Ids) that I receiv

3条回答
  •  萌比男神i
    2020-12-01 11:31

    By the docs using async or launch on the instance of GlobalScope is highly discouraged, application code usually should use application-defined CoroutineScope.

    If we look at the definition of GlobalScope we will see that it is declared as object:

    object GlobalScope : CoroutineScope { ... }
    

    An object represents a single static instance(Singleton). In Kotlin/JVM a static variable comes into existence when a class is loaded by the JVM and dies when the class is unloaded. When you first use of GlobalScope it will be loaded into the memory and stay there until one of the following happens:

    1. the class is unloaded
    2. the JVM shuts down
    3. the process dies

    So it will consume some memory while your server application is running. Even if your server app is finished running but process is not destroyed, a launched coroutine may still be running and consume the memory.

    Starting a new coroutine from the global scope using GlobalScope.async or GlobalScope.launch will create a top-level "independent" coroutine.

    The mechanism providing the structure of the coroutines is called structured concurrency. Let's see what benefits structured concurrency has over global scopes:

    • The scope is generally responsible for child coroutines, and their lifetime is attached to the lifetime of the scope.
    • The scope can automatically cancel child coroutines if something goes wrong or if a user simply changes their mind and decides to revoke the operation.
    • The scope automatically waits for completion of all the child coroutines. Therefore, if the scope corresponds to a coroutine, then the parent coroutine does not complete until all the coroutines launched in its scope are complete.

    When using GlobalScope.async there is no structure that binds several coroutines to a smaller scope. The coroutines started from the global scope are all independent; their lifetime is limited only by the lifetime of the whole application. It is possible to store a reference to the coroutine started from the global scope and wait for its completion or cancel it explicitly, but it won't happen automatically as it would with a structured one. If we want to cancel all coroutines in the scope, with structured concurrency, we only need to cancel the parent coroutine and this automatically propagates cancellation to all the child coroutines.

    If you don't need to scope a coroutine to a specific lifetime object and you want to launch a top-level independent coroutine which is operating on the whole application lifetime and is not cancelled prematurely and you don't want to use the benefits of the structured concurrency, then go ahead and use global scopes.

提交回复
热议问题