Open In App

Dispatchers in Kotlin Coroutines

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite: Kotlin Coroutines on Android

It is known that coroutines are always started in a specific context, and that context describes in which threads the coroutine will be started in. In general, we can start the coroutine using GlobalScope without passing any parameters to it, this is done when we are not specifying the thread in which the coroutine should be launch. This method does not give us much control over it, as our coroutine can be launched in any thread available, due to which it is not possible to predict the thread in which our coroutines have been launched.

Kotlin




class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // coroutine launched in GlobalScope
        GlobalScope.launch() {
        Log.i("Inside Global Scope ",Thread.currentThread().name.toString())
            // getting the name of thread in
            // which our coroutine has been launched
        }
  
        Log.i("Main Activity ",Thread.currentThread().name.toString())
    }
}


log output is shown below:

Log Output

We can see that the thread in which the coroutine is launched cannot be predicted, sometimes it is DefaultDispatcher-worker-1, or DefaultDispatcher-worker-2 or DefaultDispatcher-worker-3.

How Dispatchers solve the above problem?

Dispatchers help coroutines in deciding the thread on which the work has to be done. Dispatchers are passed as the arguments to the GlobalScope by mentioning which type of dispatchers we can use depending on the work that we want the coroutine to do. 

Types of Dispatchers

There are majorly 4 types of Dispatchers.

  1. Main  Dispatcher
  2. IO Dispatcher
  3. Default Dispatcher
  4. Unconfined Dispatcher

Main Dispatcher:

It starts the coroutine in the main thread. It is mostly used when we need to perform the UI operations within the coroutine, as UI can only be changed from the main thread(also called the UI thread).

Kotlin




GlobalScope.launch(Dispatchers.Main) {
       Log.i("Inside Global Scope ",Thread.currentThread().name.toString())
           // getting the name of thread in which 
              // our coroutine has been launched
       }
       Log.i("Main Activity ",Thread.currentThread().name.toString())


The main Dispatcher Log Output

IO Dispatcher:

It starts the coroutine in the IO thread, it is used to perform all the data operations such as networking, reading, or writing from the database, reading, or writing to the files eg: Fetching data from the database is an IO operation, which is done on the IO thread.

Kotlin




GlobalScope.launch(Dispatchers.IO) {
       Log.i("Inside IO dispatcher ",Thread.currentThread().name.toString())
           // getting the name of thread in which
              // our coroutine has been launched
       }
       Log.i("Main Activity ",Thread.currentThread().name.toString())


IO Dispatcher Log-Output

Default Dispatcher:

It starts the coroutine in the Default Thread. We should choose this when we are planning to do Complex and long-running calculations, which can block the main thread and freeze the UI eg: Suppose we need to do the 10,000 calculations and we are doing all these calculations on the UI thread ie main thread, and if we wait for the result or 10,000 calculations, till that time our main thread would be blocked, and our UI will be frozen, leading to poor user experience. So in this case we need to use the Default Thread. The default dispatcher that is used when coroutines are launched in GlobalScope is represented by Dispatchers. Default and uses a shared background pool of threads, so launch(Dispatchers.Default) { … } uses the same dispatcher as GlobalScope.launch { … }.

Kotlin




GlobalScope.launch(Dispatchers.Default) {
        Log.i("Inside Default dispatcher ",Thread.currentThread().name.toString())
            // getting the name of thread in which 
              // our coroutine has been launched
        }
        Log.i("Main Activity ",Thread.currentThread().name.toString())


deafult dispatcher

Unconfined Dispatcher:

As the name suggests unconfined dispatcher is not confined to any specific thread. It executes the initial continuation of a coroutine in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. 



Last Updated : 10 Sep, 2020
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads