Java:并发速度比简单的 for 循环慢

标签 java image swing concurrency

我必须用自定义图像的内容填充 BufferedImage,因为我想在 JFrame 中显示自定义图像。

在使用探查器检查代码之前,我使用了一个简单的 for-Loop:

for(int x = 0; x < width, x++)
    for(int y = 0; y < height; y++)
        bufferedImage.setRGB(x, height-y-1, toIntColor( customImage.get(x,y) ));

这有效,但我决定并发尝试。此代码将图像分为几列,并且应该并行复制每列(简化的代码片段):

final ExecutorService pool = Executors.newCachedThreadPool();
final int columns = Runtime.getRuntime().availableProcessors() +1;
final int columnWidth = getWidth() / columns;

for(int column = 0; column < columns; column++){
        final Rectangle tile = Rectangle.bottomLeftRightTop(
                0,
                columnWidth*column,
                columnWidth*(column+1),
                height
        );

        pool.execute(new ImageConverter(tile));
}


pool.shutdown();
pool.awaitTermination( timeoutSeconds, TimeUnit.SECONDS);

图像转换器可运行:

private final class ImageConverter implements Runnable {
    private final Rectangle tile;
    protected ImageConverter(Rectangle tile){ this.tile = tile;  }

    @Override public void run(){
        for(int x = tile.left; x < tile.right; x++)
            for(int y = tile.bottom; y < tile.top; y++)
                bufferedImage.setRGB(x, height-y-1, toIntColor( customImage.get(x,y) ));        }
}

我注意到并发解决方案比简单的 for 循环花费的时间大约是两到三倍。 我已经寻找过这样的问题并用谷歌搜索,但我没有找到任何东西。

为什么要花这么长时间? 是因为awaitTermination()行吗? 是否有更好的图像转换解决方案?

提前致谢,约翰内斯:)

编辑:

我已经进行了一些测试。 测量的所有转换之前均进行了 3000 次图像转换的预热。

简单的 for 循环需要 7 到 8 毫秒来复制位图。

并行图像复制每个图像需要 20 到 24 毫秒。没有预热,需要 60 毫秒。

最佳答案

使用线程不会加快执行速度(常见的误解)。我的假设是使用线程的开销导致程序运行速度变慢。上下文切换非常昂贵。

一般来说,当某些事情发生阻塞时,线程很有用。我在您提供的内容中没有看到任何阻止代码。

关于Java:并发速度比简单的 for 循环慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31989463/

相关文章:

java - A* 寻路游戏系统退出问题

java - Jackson json 属性(字符串)到实例

java - 如何在不损失质量的情况下减小 BufferedImage 大小

java - 如何使用 Java 从网站获取 favicon.ico?

php - crop - scale - center & fit an image into a round 缩略图

java - Lombok 没有生成 getter 和 setter

java - 关闭 Spring Boot 应用程序时无法取消注册 DataSource JMX MBean

java - 如何让 java swing 组合框显示数组中的列而不是它正在显示的内容?

java - 如果语句和 Swing 没有按预期工作,如何让 EDT 进入休眠状态?

java - Run 方法被调用,但不会绘制