2013-12-17 36 views
1

通過下面的代碼片段,我真的很困惑:Java線程的代碼流

@Component 
public class DrawingFileExplorer { 

    private final ExecutorService pool = Executors.newFixedThreadPool(10); 

     public void explore(File drawingFolder) throws InterruptedException {  
      for(File each : drawingFolder.listFiles(DrawingFileFilter.getInstance())) { 
       if(each.isDirectory()) { 
        explore(each); 
       } else { 
        //pool.execute(new DrawingFileReviewer(each)); 
       } 
      } 
      System.out.println("THIS LINE OF CODE SHOULD BE INVOKED ONCE"); 

      pool.shutdown(); 
      pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 
     } 

} 

// Trigger of DrawingFileExplorer 
public class DrawingFileExplorerTest { 

    private static File baseFolder = new File("C:\\Users\\Jake\\Desktop\\baseFolder\\02. Current Drawings"); 

    public static void main(String[] args) throws InterruptedException { 
     ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/applicationContext.xml"); 
     DrawingFileExplorer drawingFileExplorer = (DrawingFileExplorer) ctx.getBean("drawingFileExplorer"); 
     drawingFileExplorer.explore(baseFolder); 
    } 

} 

正如我知道線路的System.out.println(..)之後的foreach應該只被調用一次。 但代碼的輸出如下。

THIS LINE OF CODE SHOULD BE INVOKED ONCE 
THIS LINE OF CODE SHOULD BE INVOKED ONCE 

任何人都可以解釋它是如何被調用兩次?由於關閉(),我的線程在第一個輸出和第二個輸出線之間沒有執行。

+2

探索正在調用自己。 – BevynQ

+0

聽到答案後聽起來很平凡的問題 –

回答

0

有檢查是否each是一個目錄後遞歸調用,那就是 -

if(each.isDirectory()) { 
    explore(each); // <-- HERE 

所以你會得到你行的多個(S),如果(且僅當)有子目錄。

0

你的方法是遞歸的,所以你爲什麼期望它不會被反覆調用(每個目錄一次)?

0

您的explore是遞歸方法,它可以根據目錄數量甚至多次調用。

for(File each : drawingFolder.listFiles(DrawingFileFilter.getInstance())) { 
       if(each.isDirectory()) { 
        explore(each); // this call is inside for loop and will be invoke recursively. 
       } else { 
        //pool.execute(new DrawingFileReviewer(each)); 
       } 
      } 

對於例如,給定的目錄結構將打印5倍線,

DraginFolder

SubFolder1

SubFolder2 

SubFolder3

SubFolder4

0

你必須移動

System.out.println("THIS LINE OF CODE SHOULD BE INVOKED ONCE"); 
pool.shutdown(); 
pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 

explore

外面當上的目錄執行的代碼僅包含的文件,上面的3行代碼會被執行。而且,因爲您關閉了該池,所以您將無法瀏覽所有文件。

0
@Component 
public class DrawingFileExplorer { 

    private final ExecutorService pool = Executors.newFixedThreadPool(10); 

    public void explore(File drawingFolder) throws InterruptedException { 
     _explore(drawingFolder); 

     pool.shutdown(); 
     pool.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); 
    } 

    private void _explore(File drawingFolder) { 
     for(File each : drawingFolder.listFiles(DrawingFileFilter.getInstance())) { 
      if(each.isDirectory()) { 
       _explore(each); 
      } else { 
       pool.execute(new DrawingFileReviewer(each)); 
      } 
     } 
    } 

} 

使另一個_explorer(..)方法來解決它謝謝。