runBlocking in Kotlin Coroutines with Example

10 Sep, 2021
Prerequisite:
Kotlin Coroutines on Android
Suspend Function In Kotlin Coroutines
As it is known that when the user calls the delay() function in any coroutine, it will not block the thread in which it is running, while the delay() function is called one can do some other operations like updating UI and many more things. As the delay function is a suspend function it has to be called from the coroutine or another suspend function.
According to official documentation, the runBlocking() function may be defined as:
runBlocking is a coroutine function. By not providing any context, it will get run on the main thread.Runs a new coroutine and blocks the current thread interruptible until its completion. This function should not be used from a 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.
Kotlin
// sample program in android studio to demonstrate coroutinespackage com.example.gfgcoroutines  import androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.util.Logimport android.widget.Toastimport kotlinx.coroutines.GlobalScopeimport kotlinx.coroutines.delayimport kotlinx.coroutines.launch  class MainActivity : AppCompatActivity() {    val TAG:String="Main Activity"    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        GlobalScope.launch(Dispatchers.Main) {            delay(3000)            Log.d(TAG,"User is in the Global Scope ")            Toast.makeText(applicationContext,"User is in the Global Scope ",Toast.LENGTH_SHORT).show()        }        Log.d(TAG,"User is not in the Global Scope ")        Toast.makeText(applicationContext,"User is not in the Global Scope ",Toast.LENGTH_SHORT).show()    }}
Log Output:
Log-Output of the above program (Timestamps in seconds is shown by Oval Circle in image)
As it can be seen in the log-output that the “User is in the Global Scope” gets printed after the Log of “User is not in the Global Scope” which shows that the GlobalScope start a coroutine, which does not block the main thread, and the other operations can be performed while the delay time get’s over. But when someone wants to call only the suspend function and do not need the coroutine behavior, one can call the suspend function from the runBlocking. So when one wants to call any suspend functions such as delay() and do not care about the asynchronous nature, one can use the runBlocking function. The difference between the calling the suspend function from the GlobalScope.launch{ } and calling the suspend function (eg delay()) from runBlocking{ } is that runBlocking will block the main thread or the thread in which it is used and GlobalScope.launch{ } will not block the main thread, in this case, UI operations can be performed while the thread is delayed.
Another use-case of runBlocking is for testing of the JUnit, in which one needs to access the suspend function from within the test function. One case also uses the runBlocking in order to learn the coroutines in-depth in order to figure out how they work behind the scenes. Let’s see from the examples below how runBlocking actually works:
Kotlin
package com.example.gfgcoroutinesimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.util.Logimport android.widget.Toastimport kotlinx.coroutines.GlobalScopeimport kotlinx.coroutines.delayimport kotlinx.coroutines.launch  class MainActivity : AppCompatActivity() {    val TAG="Main Activity"    override fun onCreate(savedInstanceState: Bundle?)     {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)                  Log.d(TAG,"Before run-blocking")            runBlocking               {              Log.d(TAG,"just entered into the runBlocking ")              delay(5000)                Log.d(TAG,"start of the run-blocking")              Log.d(TAG,"End of the runBlocking")            }        Log.d(TAG,"after the run blocking")    }}
Log Output:
Log-Output of the above program  (Timestamps in seconds is shown by Oval Circle in image)
The Round oval circle in the above log-output shows the timestamps in which the log output is being printed. It can be clearly seen that when the “just entered into the runBlocking” the delay of 5 sec is encountered, so other operations can not be performed and have to wait for 5 seconds. The Log statement “after the run blocking” which is outside of the runBlocking function too, has to wait for the whole runBlocking function to finish its work. Let’s take another example and try to learn how runBlocking works and how different coroutines can be launched within it.
Kotlin
package com.example.gfgcoroutinesimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.util.Logimport android.widget.Toastimport kotlinx.coroutines.GlobalScopeimport kotlinx.coroutines.delayimport kotlinx.coroutines.launch  class MainActivity : AppCompatActivity() {    val TAG="Main Activity"    override fun onCreate(savedInstanceState: Bundle?)     {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)                  Log.d(TAG,"Before run-blocking")             runBlocking                {              Log.d(TAG,"just entered into the runBlocking ")              delay(5000)              launch(Dispatchers.IO)             {                delay(3000L)                Log.d(TAG,"Finished to coroutine 1")             }               launch(Dispatchers.IO)             {                delay(3000L)                Log.d(TAG,"Finished to coroutine 2")             }              Log.d(TAG,"start of the run-blocking")              Log.d(TAG,"End of the runBlocking")             }         Log.d(TAG,"after the run blocking")         GlobalScope.launch          {            Log.d(TAG,"Logging in the globalScope")         }    }}
Log Output:
Log-Output of the above program  (Timestamps in seconds is shown by Oval Circle in image)
It can be seen in the above log-output that both GlobalScope and launch will execute after the delay of runBlocking. As both the coroutine which are launched within runBlocking with launch function will be executed within the same thread, it seems like both the coroutine are running in parallel, but it is not possible since both are running in the same thread, but they are running in an asynchronous manner. So it can be said that users should use coroutine runBlocking only when the user wants to do a JUnit test or want to call only the suspend functions.
sagar0719kumar
android
Android
Kotlin
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.