17

Is there any difference between this two approaches?

runBlocking {
   launch(coroutineDispatcher) {
      // job
   }
}
GlobalScope.launch(coroutineDispatcher) {
   // job
}
Sergio
  • 27,326
  • 8
  • 128
  • 149
silent-box
  • 1,649
  • 3
  • 21
  • 40

2 Answers2

30

runBlocking runs new coroutine and blocks current thread interruptibly until its completion. This function should not be used from coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.

// line 1
runBlocking {
   // line 2
   launch(coroutineDispatcher) {
      // line 3
   }
   // line 4
}
// line 5
someFunction()

In case of using runBlocking lines of code will be executed in the next order:

line 1
line 2
line 4
line 3
line 5 // this line will be executed after coroutine is finished

Global scope is used to launch top-level coroutines which are operating on the whole application lifetime and are not cancelled prematurely. Another use of the global scope is operators running in Dispatchers.Unconfined, which don't have any job associated with them. Application code usually should use application-defined CoroutineScope, using async or launch on the instance of GlobalScope is highly discouraged.

// line 1
GlobalScope.launch(coroutineDispatcher) {
   // line 2
}
// line 3
someFunction()

In case of using GlobalScope.launch lines of code will be executed in the next order:

line 1
line 3
line 2

Thus runBlocking blocks current thread until its completion, GlobalScope.launch doesn't.

Sergio
  • 27,326
  • 8
  • 128
  • 149
  • Thank you, but I still confused. Everywhere it is written, that use of GlobalScope is discouraged - but I don't see any difference for my case (Spring's PostConstruct, which initiates SEDA mechanism). If I'm specifing custom coroutine dispatcher, what is the difference between 2 approaches in my case? – silent-box Feb 24 '19 at 23:42
  • There is a good discussion why using of GlobalScope is discouraged https://stackoverflow.com/questions/54335365/why-not-use-globalscope-launch. – Sergio Feb 25 '19 at 06:16
0

I will try a different explanation without repeating the existing standard answers.

The "coroutine scope" is the boundary where the coroutine exists. The "global scope" exists as long as the application process is running. If you use "GlobalScope.launch()" you create a global coroutine that lives in the application scope.

If you use "runBlocking { launch() }" you create a coroutine that lives in the local block just after runBlocking. That local block will not exit as long as the coroutines in it are alive.

Bruno Ranschaert
  • 7,428
  • 5
  • 36
  • 46