Here's a quick rundown of my predicament. I am leaing multi-threading and therefore decided to make a thumbnail creator program to process around 300 images. At first, I did all the thumbnail creation on a single thread and that took around 99 seconds. So I figured that using newFixedThreadPool() would make the program faster. I have heard that using Executors.newFixedThreadPool() is less expensive than manually creating threads. So I did ExecutorService executor = Executors.newFixedThreadPool(4);
4 being the number of cores on my machine.
The strange thing is that doing this made the program slower. When I used one thread in the newFixedThreadPool, the tasks were completed in around 118 seconds. When I used 4 threads, the tasks were completed in around 99 seconds. A few milliseconds slower than the initial single threaded operation. When I used 10 threads, the time taken was around 110 seconds.
I have absolutely no idea on how to make the program faster. I was thinking that using 4 threads is optimal and it would allow for the work to be done in around a quarter of the time the single threaded operation took.
Does anyone have any suggestions on what can be done? Here is my (very ugly code)
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 Ruable {
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");
}
}
}
