0

The official document about runBlokcing says

Runs a new coroutine and blocks the current thread 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.

I think it means that runBlocking blocks only current thread.

but the Kotlin Coroutines Deep Dive by written Marcin Moskała.
In the book, it says

"Using a dispatcher, we can make runBlocking run on a different thread. But still, the thread on which this builder has been started will be blocked until the coroutines is done."

I understood it even if i change the current thread to worker(or other) thread with withContext or something and run the 'runBlocking' in the worker thread, the runBlocking will still block all the thread including main thread.

Therefore, what i want to know is runBlocking always block the main thread no matter what ways i use?

CodingBruceLee
  • 657
  • 1
  • 5
  • 19

2 Answers2

6

Those quotes both say it blocks the current thread. Which is what it does. If you use it on the main thread, then it blocks the main thread. If you use it on another thread, it blocks that one.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
4

runBlocking only blocks a single thread, the one that it was called on.

The book quote doesn’t contradict the documentation. Maybe your source of confusion about what the book is saying is thinking “the coroutine” in the phrase “until the coroutine is done” is referring to the outer coroutine that (shamefully) called runBlocking, when it is actually referring to the unrelated runBlocking coroutine.

You should never use runBlocking inside a coroutine in the first place. There is no situation or condition where it would ever make sense to do that. Almost the only two places you will ever use runBlocking is directly in a JVM’s main() function or in a unit test. But also you might need it to use coroutines synchronously in a non-suspending callback function.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Thank you. As you said, i think I was confused because of that sentence. Technically, i was reading a part of using `runblocking` in `main()` function. So, there is no reason to use `runBlocking` in a coroutine. :) but i have a question. i can see some questions that they want to use `runBlocking` in Retrofit `interceptor` or `Authenticator`. Do you think it's fine? because if i use `runBlocking` in them, it might block main thread. – CodingBruceLee Jul 06 '23 at 05:06
  • It depends on whether the interceptor or Authenticator interfaces are called on the main thread or not. I’m not familiar enough with Retrofit to know under which conditions they will be called on the main thread. Maybe this is relevant: https://stackoverflow.com/q/28021485/506796 – Tenfour04 Jul 06 '23 at 05:13
  • Oh, so the book quote is talking about changing the dispatcher used internally by the runBlocking coroutine to run its code. Sometimes you want to do that if you need to do parallel *blocking* work so you need more than one thread working. – Tenfour04 Jul 06 '23 at 05:16
  • Yes. as you mentioned, the book and document are right. the only problem was that i misunderstood the content of the book. haha So, what i wanted to try was like below. `fun main() { val thread = Thread { runBlocking(Dispatchers.IO) { println("my thread") } } thread.start() println("End") } ` // my thread // End `runBlocking` that is in the new `Thread` only blocks the new thread not main thread. So, it's fine. And if i use Retrofit, It should be fine as long as it operates on the worker thread. Thank you Tenfour04 :-) – CodingBruceLee Jul 07 '23 at 00:27