Tarun Chawla
Tarun Chawla

Reputation: 538

Does "withContext" create a new coroutine?

I have the following code:

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        println("in sub coroutine ${Thread.currentThread().name}")
    }
    println("before coroutine in main ${Thread.currentThread().name}")
    withContext(Dispatchers.IO) {
        println("hello from coroutine ${Thread.currentThread().name}")
        delay(1500)
        println("hello from coutoutine after delay ${Thread.currentThread().name}")
    }
    println("after coroutine in main ${Thread.currentThread().name}")
}

The output is:

before coroutine in main main @coroutine#1
hello from coroutine DefaultDispatcher-worker-1 @coroutine#1
in sub coroutine main @coroutine#2
hello from coutoutine after delay DefaultDispatcher-worker-1 @coroutine#1
after coroutine in main main @coroutine#1

My understanding is that withContext switches the code to a new context where code is executed in a different thread, and the current coroutine is suspended until the code in the new thread is completed. But the original definition does not say anything about creation of new coroutine.

Original definition from kotlin.github.io:

Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result.

Upvotes: 4

Views: 1963

Answers (2)

Tenfour04
Tenfour04

Reputation: 93659

There is no one-to-one correspondance between threads and coroutines. When a coroutine resumes from suspension, it could resume on some other thread, depending on what the Dispatcher gives it.

launch and async create new coroutines. withContext does not create a new coroutine, it only shifts the context of the existing coroutine, which is why it's a suspend function (unlike launch and async).

Upvotes: 7

Clay07g
Clay07g

Reputation: 1105

I believe you're just misreading your output.

before coroutine in main main @coroutine#1
hello from coroutine DefaultDispatcher-worker-1 @coroutine#1
in sub coroutine main @coroutine#2
hello from coutoutine after delay DefaultDispatcher-worker-1 @coroutine#1
after coroutine in main main @coroutine#1

In this output, you have 2 coroutines:

  • @coroutine#1 (via "runBlocking")
  • @coroutine#2 (via "launch")

And two threads:

  • main
  • DefaultDispatcher-worker-1

No additional coroutine is created when doing "withContext". Your two coroutines are "runBlocking" and "launch".

Upvotes: 1

Related Questions