Dispatchers in Kotlin Coroutines

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

filter_none

edit
close

play_arrow

link
brightness_4
code

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())
    }
}

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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())

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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())

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

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())

chevron_right


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. 




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :
Practice Tags :


4


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.