gpt4 book ai didi

java - 使用 ExecutorService : Doesn't use 100% of my cpu-power 在 Java 中并行重命名图像

转载 作者:行者123 更新时间:2023-11-30 11:35:24 25 4
gpt4 key购买 nike

我的并行 Java 代码有问题。我尝试从磁盘读取一些图像,更改图像的名称,然后将它们再次保存到不同的文件夹中。为此,我尝试按如下方式并行运行它:

    int nrOfThreads = Runtime.getRuntime().availableProcessors();
int nrOfImagesPerThread = Math.round(remainingImages.size()/((float)nrOfThreads));

ExecutorService ex2 = Executors.newFixedThreadPool(nrOfThreads);
int indexCounter = 0;
for(int i = 0; i< nrOfThreads; ++i) {
if(i != (nrOfThreads-1)) {
ex2.execute(new ImageProcessing(remainingImages.subList(indexCounter, indexCounter+nrOfImagesPerThread), newNames.subList(indexCounter,indexCounter+nrOfImagesPerThread)));
indexCounter+=nrOfImagesPerThread;
}else {
ex2.execute(new ImageProcessing(remainingImages.subList(indexCounter, remainingImages.size()), newNames.subList(indexCounter,remainingImages.size())));
}
}


ex2.shutdown();

try {
ex2.awaitTermination(12, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}

这是 ImageProcessing 类:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;

public class ImageProcessing implements Runnable {

private List<String> oldPaths;
private List<String> newPaths;

public ImageProcessing(List<String> oldPaths, List<String> newPaths) {
this.oldPaths = oldPaths;
this.newPaths = newPaths;
}

@Override
public void run() {
for(int i = 0; i< oldPaths.size();++i) {
try {
BufferedImage img = ImageIO.read(new File(oldPaths.get(i)));
File output = new File(newPaths.get(i));
ImageIO.write(img, "jpg", output);
} catch (IOException e) {
e.printStackTrace();
}
}
}

我将 for 循环中的图像位置分成(线程数)部分,所以在我的例子中大约有 8 个部分。当我现在运行代码时,它确实是并行运行的,但它并没有使用 100% 的 cpu 能力。它只使用每个处理器的大约 25%。

有人知道为什么会这样吗?还是我只是在编程的某个地方搞砸了?

非常感谢!

编辑:为了让寻求相同功能的人完成任务,我查看了 Apache 公共(public)库 (see here) 并找到了一种不错且更快的方法来从中复制图像一个硬盘到另一个。 ImageProcessing 类现在如下所示:

import java.io.File;
import java.io.IOException;
import java.util.List;


import org.apache.commons.io.FileUtils;


public class ImageProcessing implements Runnable {

private List<String> oldPaths;
private List<String> newPaths;

public ImageProcessing(List<String> oldPaths, List<String> newPaths) {
this.oldPaths = oldPaths;
this.newPaths = newPaths;
}

@Override
public void run() {
for(int i = 0; i< oldPaths.size();++i) {
File sourceFile = new File(oldPaths.get(i));

File targetFile = new File(newPaths.get(i));
//copy file from one location to other
try {
FileUtils.copyFile(sourceFile, targetFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}

最佳答案

你的问题是,这里的瓶颈肯定是磁盘的 I/O。您可能需要在没有 ExecutorService 的情况下同时重命名文件。

换句话说:将更改(重命名文件)写入磁盘所消耗的时间比 CPU 使用的时间还多。

你不能多线程这样的 Action 。

只需测量代码的串行(非多线程)版本所需的时间,并将其与多线程代码所需的时间进行比较。它或多或少是一样的。

关于java - 使用 ExecutorService : Doesn't use 100% of my cpu-power 在 Java 中并行重命名图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15161272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com