这是我的困境的快速概述。我正在学习多线程,因此决定制作缩略图创建程序来处理大约300张图像。
起初,我在一个线程上创建了所有缩略图,大约需要99秒。
所以我认为使用newFixedThreadPool()
会使程序更快。我听说使用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");
}
}
}