添加更多线程会增加我的程序的性能

时间:2012-01-05 02:32:53

标签: java multithreading performance

在我的程序中,我有一个while循环,它遍历一堆图片的数组列表,并对它们进行一系列处理,以改变它们的外观和图像类型,然后将它们写入磁盘。我的问题是添加多个线程来处理图像或保存图像加快速度,如果是这样,最好的方法是什么。     ArrayList images = new ArrayList(); //超过500个图像     ArrayList paths = new ArrayList();     int len = images.size();

for (int i =0; i < len ; i ++)
{
BufferedImage image  = process (images.get(i))//takes about a second 
ImageIO.write(image, "jpg", new File(getImagePaths().get(i)));


}

2 个答案:

答案 0 :(得分:3)

您可以将列表划分为n个块,以便您拥有list / n大小的块,然后您可以在这些“块”图像上运行n个线程。通过这种方式,您可以同时完成更多工作。

为了解决一些问题,它很可能会增加I / O并发性,因为在单线程运行中它会在第一次未命中和阻塞时出错,然后再次出错以读取第二个图像等等...在多线程方式中,它将一次阻止n个图像,这允许I / O调度器一次处理更多I / O(这通常是一件好事)。这意味着即使在单核处理器中性能也会提高,这是因为I / O的重叠以及在I / O线程被阻塞等待时在核心上运行的线程数量更多的可用性。

答案 1 :(得分:2)

是的,很有可能因为:

1)您的计算机可能有2到4个CPU或核心

2)图像处理通常是CPU密集型的

3)因此,大CPU负载可以分成多个同时运行的任务。

这总是有效吗?

没有。如果您的进程是i / o(互联网,磁盘或内存)有界(例如,它需要每个映像2G的内存,或者它必须编写大量的临时文件),您将看不到线性加速 - 因为CPU速度的增加将被执行i / o的时间所抵消,这将使您的程序变慢,无论您​​需要多少处理器来共享图像处理的负载。 就像煮面条一样 - 煮面条需要10分钟。即使你有8个不同的燃烧器同时进行 - 吸入面条的水仍然需要10分钟,所以不会有帮助。

Psuedo代码:

   //just a reminder ! 
   public static final int MAX_SEM=8;
   processAll()
   {
     //create a new semaphore with 4 slots.
     semaphore = new Semaphore(MAX_SEM) ;
     while(! images.empty())
         if(semaphore has a slot) 
           Image img=images.pop();
           sempahore.decrement()
           Thread().run( new Runable() { public void run() {process(img);} } 
         else
           Thread.sleep(1000);
    }

    process(Image i)
    {   do some work  on i 
        semaphore.increment()
    }