2013-12-17 37 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(..)方法来解决它谢谢。