这是我的困境的简要概述。我正在学习多线程,因此决定制作一个缩略图创建程序来处理大约 300 张图像。起初,我在一个线程上完成了所有缩略图的创建,这花费了大约 99 秒。所以我认为 usingnewFixedThreadPool()
会使程序更快。我听说使用Executors.newFixedThreadPool()
比手动创建线程便宜。所以我做了:
ExecutorService executor = Executors.newFixedThreadPool(4);
4 是我机器上的核心数。
奇怪的是,这样做会使程序变慢。当我在 中使用一个线程时newFixedThreadPool
,任务在大约 118 秒内完成。当我使用 4 个线程时,任务在大约 99 秒内完成。比初始单线程操作慢几毫秒。当我使用 10 个线程时,所用时间约为 110 秒。
我完全不知道如何使程序更快。我在想使用 4 个线程是最佳的,它可以让工作在单线程操作所用时间的大约四分之一内完成。
有人对可以做什么有任何建议吗?这是我的(非常丑陋的代码)
public class Thumbnails {
protected static BufferedImage image = null;
protected static BufferedImage outBM;
protected static Graphics2D g2d;
public static void main(String[] args) {
long start = System.currentTimeMillis();
File f = new File("/home/njengah/Media/Images");
File[] myPics = f.listFiles();// list of all images folder
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < myPics.length; i++) {
executor.submit(new Thumbnails().new ImgProcessor(myPics[i]));
}
System.out.println(" all tasks submitted ");
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(" image processing completed.");
long stop = System.currentTimeMillis();
System.out.println("time taken to process all images: "+(stop - start));
}
// this handles the processing of a single image
protected static void singleImageProcessor(File onePic) throws IOException {
image = ImageIO.read(onePic);
outBM = new BufferedImage((int) (image.getWidth() * 0.1), (int) (image.getHeight() * 0.1), image.getType());
g2d = outBM.createGraphics();
g2d.drawImage(image, 0, 0, (int) (image.getWidth() * 0.1), (int) (image.getHeight() * 0.1), null);
g2d.dispose();
ImageIO.write(outBM, onePic.getName().split("\\.")[1], new File("/home/njengah/Downloads/resized/" + onePic.getName()));
}
private class ImgProcessor implements Runnable {
File onePic;
public ImgProcessor(File onePic) {
this.onePic = onePic;
}
@Override
public void run() {
// this runs one task
System.out.println("starting");
try {
singleImageProcessor(onePic); // single task
} catch (Exception e) {
e.printStackTrace();
} // to make it shut up
System.out.println("finished");
}
}
}