我尝试使用所有CPU内核尽快填充图像(在JavaFx中),但我遇到了一些问题。下面是我能想出的最小的例子来重现问题。
当我使用join()
函数创建的Job
上调用launch
时,图像呈现正确,但显然只使用了一个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)
}