2014-09-29 57 views
0

我有一個程序,它探索文件系統,從一個給定的root.the程序遞歸地探索從根點的所有目錄,並在tiff文件上執行一個過程。確實它合併了每個兩個tiff文件。我使用ExecutorService和ThreadPoolExecutor來處理合並函數。java:線程完全不能完成run()方法嗎?

 ExecutorService exec = Executors.newFixedThreadPool(threadsNumber); 
    inputDirectoryProcess(inputDir); 
    exec.shutdown(); 
    try { 
     exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

成爲每一個合併功能我用以下:

exec.submit(new MultipageTask(a, Integer.toString(intDetector(directoryFiles.get(i + 1).getName())/2), out)); 

以下是MultipageTask類:

 public void run() { 

     Thread thread = Thread.currentThread(); 
     System.out.println("start by " + thread.getName() + " (" + thread.getId() + ")"); 

     Integer[] resoulutions = null; 

     try { 

      BufferedImage image[] = new BufferedImage[tifImages.length]; 
      for (int i = 0; i < tifImages.length; i++) { 
       resoulutions = getsize(tifImages[i].getPath()); 
       SeekableStream ss = null; 
       ss = new FileSeekableStream(tifImages[i]); 
       ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", ss, null); 

       PlanarImage op = null; 
       op = new NullOpImage(decoder.decodeAsRenderedImage(0), 
         null, OpImage.OP_IO_BOUND, null); 
       image[i] = op.getAsBufferedImage(); 
      } 

      TIFFField[] fields = new TIFFField[3]; 
      // ResolutionUnit 
      TIFFField fieldResUnit = new TIFFField(296, TIFFField.TIFF_SHORT, 1, 
        (Object) new char[] { 2 }); 
      fields[0] = fieldResUnit; 

      // XResolution 
      TIFFField fieldXRes = new TIFFField(282, TIFFField.TIFF_RATIONAL, 1, 
        (Object) new long[][] { { resoulutions[0], 1 } }); 
      fields[1] = fieldXRes; 

      // YResolution 
      TIFFField fieldYRes = new TIFFField(283, TIFFField.TIFF_RATIONAL, 1, 
        (Object) new long[][] { { resoulutions[1], 1 } }); 
      fields[2] = fieldYRes; 

      TIFFEncodeParam params = new TIFFEncodeParam(); 
      params.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4); 
      params.setExtraFields(fields); 
      OutputStream out = new FileOutputStream(outDir + "\\" + image_name + ".tif"); 
      ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, params); 
      Vector vector = new Vector(); 
      for (int i = 1; i < tifImages.length; i++) { 
       vector.add(image[i]); 
      } 
      params.setExtraImages(vector.iterator()); 
      encoder.encode(image[0]); 
      out.close(); 
      System.out.println("end by " + thread.getName() + " (" + thread.getId() + ")"); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     increasetCount(); 
    } 
} 

public synchronized void increasetCount() { 
    convertCount = convertCount + 2; 
    updateBar(convertCount); 
} 

節目結束後,我注意到,一些文件沒有處理。所以我登錄進入和退出線程如上所示。在控制檯中,我看到以下幾行:

start by pool-2-thread-4 (30) 
end by pool-2-thread-2 (28) 
start by pool-2-thread-2 (28) 
start by pool-2-thread-4 (30) 
start by pool-2-thread-2 (28) 
start by pool-2-thread-1 (27) 
start by pool-2-thread-1 (27) 
start by pool-2-thread-4 (30) 
end by pool-2-thread-1 (27) 
end by pool-2-thread-2 (28) 
start by pool-2-thread-1 (27) 
start by pool-2-thread-2 (28) 

正如你看到一些像28啓動的線程,但沒有完成。這導致失去了一些合併過程和程序無法處理所有的tiff文件。

注:我應該提到,當我增加threadsNumber時,缺少的增加!

我該如何解決?我想確保每個線程完成運行過程。

感謝和抱歉,因爲糟糕的英語。

+0

你使用類似sempahores,鎖或條件的try/catch包圍你的代碼?如果是的話,它會死鎖。 – 2014-09-29 11:37:24

+0

你是不是使用守護進程線程(通常情況並非如此)?您可以通過調用'shutdown'來確保'ExecutorService'中的所有任務都已完成。 – 2014-09-29 11:41:31

+0

我敢打賭你的處理代碼是罪魁禍首。你能告訴我們關於它的一些事嗎? – watery 2014-09-29 11:56:21

回答

2

,如果你沒有共享資源和它不是一個死鎖/活鎖,嘗試用

public class MultipageTask implements Runnable { 
    private File[] tifImages; 
    private String image_name; 
    private String outDir; 

    public MultipageTask(File[] tifImages, String image_name, String outDir) { 
     this.tifImages = tifImages; 
     this.image_name = image_name; 
     this.outDir = outDir; 
    } 

    @Override 
    public void run() { 

     Thread thread = Thread.currentThread(); 
     System.out.println("start by " + thread.getName() + " (" + thread.getId() + ")"); 

      try{ 
       // doing merge process 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
      System.out.println("end by " + thread.getName() + " (" + thread.getId() + ")"); 


    } 
} 
+0

無論如何,當未捕獲的異常拋出時,線程是否會完成?而且,你的建議不會吞下'InterruptedException's嗎? – watery 2014-09-29 11:55:32

+1

線程將完成,但不會執行打印完成的代碼。嘗試/ catch會解決它。我只舉一個例子,他可以緩存他需要的確切異常。 – Dima 2014-09-29 11:58:51

+0

啊,我沒那麼明白:) NVM。 – watery 2014-09-29 11:59:40