繁体   English   中英

使用Kotlin协程进行多线程

[英]Multithreading using Kotlin Coroutines

我正在试验Kotlin协程,并具有以下代码:

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() }
}

这是我的输出:

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

据罗马Elizarov的回答相关问题,另一个协同程序:

“启动过程只会创建新的协程,而CommonPool会将协程分派到ForkJoinPool.commonPool(),该示例确实使用多个线程,因此在此示例中可以在多个CPU上执行。”

根据Java 8 文档

“对于需要单独或自定义池的应用程序,可以使用给定的目标并行度级别构造一个ForkJoinPool;默认情况下,它等于可用处理器的数量。”

为什么只使用3个工作线程? 即使将异步任务的数量增加到1000+,也有3个工作线程。

我的配置:Mac / High Sierra,具有双核cpu(具有超线程功能 ,因此具有4个可见内核),Kotlin 1.2,kotlinx-coroutines-core:0.19.3和JVM 1.8

如果查看CommonPool的实现,您会注意到它正在java.util.concurrent.ForkJoinPool或具有以下大小的线程池上运行:

(Runtime.getRuntime().availableProcessors() - 1).coerceAtLeast(1)

有了4可用的处理器,这将导致3结果,回答您为什么看到3个工作线程的原因。

可以如下确定ForkJoinPool -size(将是相同的):

ForkJoinPool.commonPool().parallelism

如果您使用协程版本> = 1.0,请参阅此答案

从Coroutines 1.0开始,代码将略有不同,因为CommonPool将被Dispatchers.Default取代。

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() }
}

另外,您现在将获得以下内容:

它由JVM上的共享线程池支持。 默认情况下,此调度程序使用的最大线程数等于CPU内核数,但至少为两个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM