GlobalScope.launch doesn't finish its task inside runBlocking main function

1.6k views Asked by At

I don't understand why in the program below GlobalScope.launch instruction doesn't finish its task.

I do understand that runBlocking has no control over GlobalScope and it's usually bad to use it, but that doesn't make me know why instructions inside GlobalScope.launch {} doesn't execute as expected.

The code snippet:

package coroutines

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File

fun main() = runBlocking<Unit> {
    GlobalScope.launch {
        val file = File(javaClass.getResource("/coroutines_file.txt").path)

        file.printWriter().use { out ->
            repeat(10) { i ->
                delay(100)
                out.println(i.toString())
            }
        }
    }
}

Expected output inside coroutines_file:

0
1
2
3
4
5
6
7
8
9

Actual output:

An empty file.

1

There are 1 answers

4
Marko Topolnik On BEST ANSWER

GlobalScope is just an escape hatch from structured concurrency. It can't be cancelled, it doesn't even have a Job associated with it, so it doesn't offer a top-level facility that tracks all the jobs launched inside it.

On the other hand, runBlocking establishes its own scope that you should inherit for the launched coroutine, and it automatically ensures all the child coroutines run to completion.

runBlocking<Unit> {
    launch(Dispatchers.IO) {
        val file = File(javaClass.getResource("/coroutines_file.txt").path)
        file.printWriter().use { out ->
            repeat(10) { i ->
                delay(100)
                out.println(i.toString())
            }
        }
    }
}