title: Parallel image renaming in Java with ExecutorService: Doesn't use 100% of my cpu-power
body: <p>I have a problem with my parallel Java-code. I try to read some images from the disk, change the names of the images and then save them again into a different folder.
  To do so, I tried to run it in parallel as follows:</p>
  
  <pre><code>    int nrOfThreads = Runtime.getRuntime().availableProcessors();
      int nrOfImagesPerThread = Math.round(remainingImages.size()/((float)nrOfThreads));
  
      ExecutorService ex2 = Executors.newFixedThreadPool(nrOfThreads);
      int indexCounter = 0; 
      for(int i = 0; i&lt;  nrOfThreads; ++i) {
          if(i != (nrOfThreads-1)) {
              ex2.execute(new ImageProcessing(remainingImages.subList(indexCounter, indexCounter+nrOfImagesPerThread), newNames.subList(indexCounter,indexCounter+nrOfImagesPerThread))); 
              indexCounter+=nrOfImagesPerThread;
          }else {
              ex2.execute(new ImageProcessing(remainingImages.subList(indexCounter, remainingImages.size()), newNames.subList(indexCounter,remainingImages.size()))); 
          } 
      }
  
  
      ex2.shutdown();
  
      try {
          ex2.awaitTermination(12, TimeUnit.HOURS);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  </code></pre>
  
  <p>and here is the ImageProcessing-class:</p>
  
  <pre><code>import java.awt.image.BufferedImage;
  import java.io.File;
  import java.io.IOException;
  import java.util.List;
  
  import javax.imageio.ImageIO;
  
  public class ImageProcessing implements Runnable {
  
  private List&lt;String&gt; oldPaths;
  private List&lt;String&gt; newPaths;
  
  public ImageProcessing(List&lt;String&gt; oldPaths, List&lt;String&gt; newPaths) {
      this.oldPaths = oldPaths;
      this.newPaths = newPaths;
  }
  
  @Override
  public void run() { 
      for(int i = 0; i&lt;  oldPaths.size();++i) {
          try {
              BufferedImage img = ImageIO.read(new File(oldPaths.get(i)));
              File output = new File(newPaths.get(i)); 
              ImageIO.write(img, "jpg", output);
          } catch (IOException e) { 
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I divide the image-locations in the for-loop into (number of threads)-parts, so in my case around 8 parts. When I now run the code, it does run in parallel, but it does not utilize 100% of my cpu power. It's only using around 25% of each processor. </p>
  
  <p>Does anybody have an idea why that happend? Or did I just screw up somewhere in the programming?</p>
  
  <p>Thanks a lot!</p>
  
  <p><b>Edit</b>: Just for completion for people looking for the same functionality, I had a look at the Apache commons library (<a href="http://commons.apache.org/proper/commons-io//" rel="nofollow" >see here</a>) and found a nice and much faster way to copy the images from one HDD to the other. The ImageProcessing-class looks now like the following:</p>
  
  <pre><code>import java.io.File;
  import java.io.IOException;
  import java.util.List;
  
  
  import org.apache.commons.io.FileUtils;
  
  
  public class ImageProcessing implements Runnable {
  
  private List&lt;String&gt; oldPaths;
  private List&lt;String&gt; newPaths;
  
  public ImageProcessing(List&lt;String&gt; oldPaths, List&lt;String&gt; newPaths) {
      this.oldPaths = oldPaths;
      this.newPaths = newPaths;
  }
  
  @Override
  public void run() { 
      for(int i = 0; i&lt;  oldPaths.size();++i) {
          File sourceFile = new File(oldPaths.get(i)); 
  
          File targetFile = new File(newPaths.get(i)); 
          //copy file from one location to other
          try {
              FileUtils.copyFile(sourceFile, targetFile);
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
      }
  }
  }
  </code></pre>