Seperti yang sudah kita ketahui, coroutines berjalan di atas sebuah thread. Tentunya kita harus mengetahui thread mana yang akan digunakan untuk menjalankan dan melanjutkan sebuah coroutine. Untuk menentukannya kita membutuhkan sebuah base class bernama CoroutineDispatcher. Di dalam kelas tersebut kita akan menemukan beberapa objek yang nantinya bisa digunakan untuk menentukan thread yang berfungsi menjalankan coroutines.
Dispatcher.DefaultMerupakan dispatcher dasar yang digunakan oleh semua standard builders seperti launch, async, dll jika tidak ada dispatcher lain yang ditentukan. Dispatcher.Default menggunakan kumpulan thread yang ada pada JVM. Pada dasarnya, jumlah maksimal thread yang digunakan adalah sama dengan jumlah core dari CPU.Untuk menggunakannya, Anda cukup menggunakan coroutines builder tanpa harus menuliskan dispatcher secara spesifik:
`1. launch {
2. // TODO: Implement suspending lambda here
3. }`
Namun Anda juga tetap diperbolehkan untuk menuliskannya secara eksplisit:
`1. launch(Dispatcher.Default){
2. // TODO: Implement suspending lambda here
3. }`
Dispatcher.IOSebuah dispatcher yang dapat digunakan untuk membongkar pemblokiran operasi I/O. Ia akan menggunakan kumpulan thread yang dibuat berdasarkan permintaan. Anda bisa menerapkannya dengan menambahkan Dispatcher.IO pada coroutines builder:
`1. launch(Dispatcher.IO){
2. // TODO: Implement algorithm here
3. }`
Dispatcher.UnconfinedDispatcher ini akan menjalankan coroutines pada thread yang sedang berjalan sampai mencapai titik penangguhan. Setelah penangguhan, coroutines akan dilanjutkan pada thread dimana komputasi penangguhan yang dipanggil.Sebagai contoh, ketika fungsi a memanggil fungsi b, yang dijalankan dengan dispatcher dalam thread tertentu, fungsi a akan dilanjutkan dalam thread yang sama dengan fungsi b dijalankan. Perhatikan kode berikut:Jika dijalankan maka konsol akan menampilkan hasil berikut:Artinya, coroutine telah dimulai dari main thread, kemudian tertunda oleh fungsi delay selama 1 detik. Setelah itu, coroutine dilanjutkan kembali pada thread DefaultExecutor.
`1. import kotlinx.coroutines.*
2.
3. fun main() = runBlocking<Unit> {
4. launch(Dispatchers.Unconfined) {
5. println("Starting in ${Thread.currentThread().name}")
6. delay(1000)
7. println("Resuming in ${Thread.currentThread().name}")
8. }.start()
9. }`
Starting in main
Resuming in kotlinx.coroutines.DefaultExecutor
Bersamaan dengan objek-objek tersebut, ada beberapa builder yang dapat digunakan untuk menentukan thread yang dibutuhkan:
Single Thread ContextDispatcher ini menjamin bahwa setiap saat coroutine akan dijalankan pada thread yang Anda tentukan. Untuk menerapkannya, Anda bisa memanfaatkan newSingleThreadContext()seperti kode dibawah ini:
`1. import kotlinx.coroutines.*
2.
3. fun main() = runBlocking<Unit> {
4. val dispatcher = newSingleThreadContext("myThread")
5. launch(dispatcher) {
6. println("Starting in ${Thread.currentThread().name}")
7. delay(1000)
8. println("Resuming in ${Thread.currentThread().name}")
9. }.start()
10. }`
Jalankan kode tersebut, seharusnya konsol akan menampilkan hasil berikut:
Starting in myThread
Resuming in myThread
Walaupun sudah menjalankan fungsi delay, coroutine akan tetap berjalan pada myThread.
Thread PoolSebuah dispatcher yang memiliki kumpulan thread. Ia akan memulai dan melanjutkan coroutine di salah satu thread yang tersedia pada kumpulan tersebut. Runtime akan menentukan thread mana yang tersedia dan juga menentukan bagaimana proses distribusi bebannya.Anda bisa menerapkan thread pool dengan fungsi newFixedThreadPoolContext() seperti berikut:
`1. import kotlinx.coroutines.*
2.
3. fun main() = runBlocking<Unit> {
4. val dispatcher = newFixedThreadPoolContext(3, "myPool")
5.
6. launch(dispatcher) {
7. println("Starting in ${Thread.currentThread().name}")
8. delay(1000)
9. println("Resuming in ${Thread.currentThread().name}")
10. }.start()
11. }`
Pada kode di atas, kita telah menetapkan thread myPool sebanyak 3 thread. Runtime akan secara otomatis menentukan pada thread mana coroutine akan dijalankan dan dilanjutkan. Hasil dari kode tersebut adalah:
Starting in myPool-1
Resuming in myPool-2