Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading using Kotlin Coroutines

I'm experimenting with Kotlin Coroutines and have following code:

fun main(args: Array<String>) = runBlocking {
    val cores = Runtime.getRuntime().availableProcessors()
    println("number of cores: $cores")

    val jobs = List(10) {
        async(CommonPool) {
            delay(100)
            println("async #$it on thread ${Thread.currentThread().name}")
        }
    }
    jobs.forEach { it.join() }
}

This is my output:

number of cores: 4
async number:0 on thread ForkJoinPool.commonPool-worker-2
async number:2 on thread ForkJoinPool.commonPool-worker-3
async number:3 on thread ForkJoinPool.commonPool-worker-3
async number:4 on thread ForkJoinPool.commonPool-worker-3
async number:5 on thread ForkJoinPool.commonPool-worker-3
async number:1 on thread ForkJoinPool.commonPool-worker-1
async number:7 on thread ForkJoinPool.commonPool-worker-3
async number:6 on thread ForkJoinPool.commonPool-worker-2
async number:9 on thread ForkJoinPool.commonPool-worker-3
async number:8 on thread ForkJoinPool.commonPool-worker-1

According to Roman Elizarov's answer to another coroutines related question:

"The launch just creates new coroutine, while CommonPool dispatches coroutines to a ForkJoinPool.commonPool() which does use multiple threads and thus executes on multiple CPUs in this example."

According to Java 8 documentation:

"For applications that require separate or custom pools, a ForkJoinPool may be constructed with a given target parallelism level; by default, equal to the number of available processors."

Why there are only 3 worker threads being used? There are the same 3 worker threads even when I increase number of async tasks to 1000+.

My configuration: Mac/High Sierra with dual core cpu (with Hyper-threading, thus 4 visible cores), Kotlin 1.2, kotlinx-coroutines-core:0.19.3 and JVM 1.8

like image 847
Jan Slominski Avatar asked May 23 '26 21:05

Jan Slominski


1 Answers

As of Coroutines 1.0, the code will look slightly different since CommonPool will be replaced with Dispatchers.Default now:

fun main(args: Array<String>) = runBlocking {
    val cores = Runtime.getRuntime().availableProcessors()
    println("number of cores: $cores")

    val jobs = List(10) {
        async(Dispatchers.Default) {
            delay(100)
            println("async #$it on thread ${Thread.currentThread().name}")
        }
    }
    jobs.forEach { it.join() }
}

Also, you will now get the following:

It is backed by a shared pool of threads on JVM. By default, the maximal number of threads used by this dispatcher is equal to the number CPU cores, but is at least two.

like image 123
s1m0nw1 Avatar answered May 28 '26 08:05

s1m0nw1



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!