Using runBlocking to Bridge Coroutines and Regular Code
📖 Scenario: Imagine you have a simple Kotlin program where you want to run a coroutine to fetch a message but your main function is not a coroutine. You need a way to wait for the coroutine to finish and get the result before continuing.
🎯 Goal: You will create a coroutine using runBlocking to bridge between regular code and coroutine code, then print the fetched message.
📋 What You'll Learn
Create a suspend function called fetchMessage that returns a String
Use runBlocking in the main function to call fetchMessage
Store the result of fetchMessage in a variable called message
Print the message variable
💡 Why This Matters
🌍 Real World
In real apps, you often need to call suspend functions from regular code, like in main functions or tests. <code>runBlocking</code> helps you wait for coroutine results safely.
💼 Career
Understanding how to bridge coroutines with regular code is important for Kotlin developers working on backend, Android, or desktop applications where asynchronous tasks are common.
Progress0 / 4 steps
1
Create the suspend function fetchMessage
Write a suspend function called fetchMessage that returns the string "Hello from coroutine!".
Kotlin
Hint
A suspend function is declared with the suspend keyword before fun.
2
Use runBlocking in main to call fetchMessage
Write a main function that uses runBlocking to call fetchMessage and store the result in a variable called message.
Kotlin
Hint
Use val message = runBlocking { fetchMessage() } inside main.
3
Print the message variable
Add a line inside the main function to print the message variable.
Kotlin
Hint
Use println(message) to show the message on the screen.
4
Run the program and see the output
Run the program and observe the output. It should print Hello from coroutine!.
Kotlin
Hint
Run the program and check the console output.
Practice
(1/5)
1. What is the main purpose of runBlocking in Kotlin coroutines?
easy
A. To create a new thread for running coroutines
B. To launch a coroutine without blocking the current thread
C. To cancel running coroutines immediately
D. To bridge blocking code and coroutine code by blocking the current thread until coroutine completes
Solution
Step 1: Understand the role of runBlocking
runBlocking is designed to bridge blocking and coroutine code by blocking the current thread until the coroutine inside it finishes.
Step 2: Compare with other coroutine builders
Unlike launch or async, runBlocking blocks the thread, making it suitable for main functions or tests but not for UI or performance-critical code.
Final Answer:
To bridge blocking code and coroutine code by blocking the current thread until coroutine completes -> Option D
Quick Check:
runBlocking blocks thread until coroutine finishes = C [OK]
Hint: runBlocking blocks thread until coroutine finishes [OK]
Common Mistakes:
Thinking runBlocking launches coroutine without blocking
Confusing runBlocking with launch or async
Assuming runBlocking creates a new thread
2. Which of the following is the correct syntax to use runBlocking in Kotlin?
easy
A. runBlocking[ println("Hello") ]
B. runBlocking() -> println("Hello")
C. runBlocking { println("Hello") }
D. runBlocking => { println("Hello") }
Solution
Step 1: Recall runBlocking syntax
runBlocking is a function that takes a lambda block inside curly braces to run coroutine code.
Step 2: Identify correct syntax
runBlocking { println("Hello") } uses curly braces correctly with a lambda block. Other options use invalid syntax like parentheses with arrow or square brackets.
Final Answer:
runBlocking { println("Hello") } -> Option C
Quick Check:
runBlocking uses curly braces for lambda = A [OK]
Hint: runBlocking uses curly braces for coroutine block [OK]
Common Mistakes:
Using parentheses instead of curly braces
Using arrow or square brackets incorrectly
Missing lambda block inside runBlocking
3. What will be the output of the following Kotlin code?
Step 1: Understand runBlocking and launch behavior
runBlocking blocks the main thread until all coroutines inside complete. The launch coroutine delays 100ms before printing "World".
Step 2: Trace the print statements
"Hello" is printed immediately in runBlocking, then after 100ms delay, "World" is printed by the launched coroutine.
Final Answer:
Hello
World -> Option A
Quick Check:
runBlocking waits; launch delays; prints Hello then World = D [OK]
Hint: runBlocking waits; launch delays; prints Hello then World [OK]
Common Mistakes:
Assuming launch runs immediately before println("Hello")
Ignoring delay effect
Thinking runBlocking does not wait for launch
4. Identify the error in this Kotlin code using runBlocking:
fun main() {
runBlocking {
delay(1000)
println("Done")
}
}
medium
A. runBlocking cannot be used inside main function
B. Missing import for delay function
C. delay cannot be called inside runBlocking
D. println should be outside runBlocking
Solution
Step 1: Check for necessary imports
The delay function is part of kotlinx.coroutines package and requires import kotlinx.coroutines.delay.
Step 2: Verify usage of runBlocking and delay
runBlocking can be used inside main, and delay is allowed inside runBlocking coroutine scope, so no error there.
Final Answer:
Missing import for delay function -> Option B
Quick Check:
delay needs import kotlinx.coroutines.delay = A [OK]
Hint: Import kotlinx.coroutines.delay to use delay inside runBlocking [OK]
Common Mistakes:
Thinking runBlocking can't be used in main
Assuming delay is a blocking call
Placing println outside runBlocking unnecessarily
5. You want to write a Kotlin main function that prints numbers 1 to 3 with a 500ms delay between each, using runBlocking. Which code correctly achieves this?
hard
A. fun main() = runBlocking {
for (i in 1..3) {
delay(500)
println(i)
}
}
B. fun main() {
for (i in 1..3) {
delay(500)
println(i)
}
}
C. fun main() = runBlocking {
(1..3).forEach {
launch { delay(500); println(it) }
}
}
D. fun main() {
(1..3).forEach {
Thread.sleep(500)
println(it)
}
}
Solution
Step 1: Understand runBlocking usage for sequential delay
fun main() = runBlocking {
for (i in 1..3) {
delay(500)
println(i)
}
} uses runBlocking once and delays inside a for loop, printing numbers sequentially with 500ms delay.
Step 2: Analyze other options
fun main() {
for (i in 1..3) {
delay(500)
println(i)
}
} lacks a coroutine scope, so delay() will not compile. fun main() = runBlocking {
(1..3).forEach {
launch { delay(500); println(it) }
}
} launches coroutines concurrently, printing numbers out of order. fun main() {
(1..3).forEach {
Thread.sleep(500)
println(it)
}
} uses Thread.sleep, which blocks thread but not coroutine style.
Final Answer:
fun main() = runBlocking {
for (i in 1..3) {
delay(500)
println(i)
}
} -> Option A
Quick Check:
runBlocking with sequential delay in loop = B [OK]
Hint: Use runBlocking once with delay inside loop for sequential prints [OK]
Common Mistakes:
Using runBlocking inside loop repeatedly
Launching coroutines without waiting
Using Thread.sleep instead of delay in coroutines
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.