JavaFx / Kotlin中的多线程图像呈现

我试图尽可能快地使用所有的CPU核心来填充图像(使用JavaFx),但是我遇到了一些问题。 下面是我可以想出的最小的例子,重现了这个问题。

当我用launch函数创建的Job上调用join()时,图像渲染正确,但显然只使用一个CPU内核? 这是为什么?

在这里输入图像描述

另一方面,当我没有在返回的作业上调用join()时,所有的CPU核心都被利用了,但是显然,图像渲染是不正确的,因为父方法不会等待作业完成:

在这里输入图像描述

任何方式,我可以填补所有内核,仍然看起来是正确的?

 package com.serious.business import javafx.animation.AnimationTimer import javafx.application.Application import javafx.scene.Scene import javafx.scene.canvas.Canvas import javafx.scene.image.WritableImage import javafx.scene.layout.Pane import javafx.stage.Stage import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.runBlocking class ImageTestApp: Application() { val w = 800.0 val h = 800.0 val image = WritableImage(w.toInt(), h.toInt()) var blue: Double = 0.0 override fun start(primaryStage: Stage) { val canvas = Canvas(w, h) val scene = Scene(Pane(canvas), w, h) primaryStage.scene = scene primaryStage.title = "Threaded image write" primaryStage.show() object: AnimationTimer() { override fun handle(now: Long) { blue += 0.2 blue %= 1 runBlocking { renderGradient(image, blue) } canvas.graphicsContext2D.drawImage(image, 0.0, 0.0) } }.start() } } suspend fun renderGradient(image: WritableImage, blue: Double) { val width = image.width val height = image.height val slices = 8 val band = width.toInt() / slices val writer = image.pixelWriter for (i in 0..slices-1) { val startX = i * band val endX = startX + band - 1 launch(CommonPool) { for (x in startX..endX) { for (y in 0..height.toInt() - 1) { val color = Color( x.toDouble() / width, y.toDouble() / height, blue, 1.0 ) writer.setColor(x, y, color) } } }.join() } } fun main(args: Array<String>) { Application.launch(ImageTestApp::class.java, *args) }