0

这是我的困境的简要概述。我正在学习多线程,因此决定制作一个缩略图创建程序来处理大约 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");
        }

    }

}
4

0 回答 0