2

並列 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 つの部分になります。コードを実行すると、並列に実行されますが、CPU パワーを 100% 使用していません。各プロセッサの約 25% しか使用していません。

なぜそれが起こったのか誰にも分かりますか?それとも、プログラミングのどこかで失敗したのでしょうか?

どうもありがとう!

編集:同じ機能を探している人のために完成させるために、Apache commonsライブラリ(こちらを参照)を見て、あるHDDから別のHDDにイメージをコピーするための優れたはるかに高速な方法を見つけました. 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();
        }

    }
}
}
4

1 に答える 1