使用 Kotlin 协程的多线程

标签 multithreading jvm kotlin kotlinx.coroutines

我正在尝试 Kotlin Coroutines并有以下代码:

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

根据 Roman Elizarov 的 answer到另一个与协程相关的问题:

"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."

根据 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."

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

我的配置: Mac/High Sierra,具有双核 cpu(具有 Hyper-threading,因此 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

请参阅 this answer如果您使用协程版本 >= 1.0

关于使用 Kotlin 协程的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47591733/

相关文章:

Java 泛型 - 为什么 new Money<Dollar>(4.0) === new Money<Franc>(4.0) 相等?

java - 测量特定监视器上的线程争用

kotlin - Kotlin 中 Lock.withLock 和 synchronized 的区别

java - 如何创建一个 Whatsapp 按钮来向我的 Android 应用程序中的特定联系人发送消息?

Java:将 keyListener 添加到已经可见的 JFrame

java - java中如何结束一个线程?

java - 如何从绘图线程(SurfaceView)调用另一个 Activity

java - 创建一个 "Lock"类(它扩展了 Object 并且什么都不做)有什么好处?

android - onKeyEvent 修饰符在 Jetpack Compose 中不起作用

exception - Java 异常的内部原理