java线程代码流程

时间:2013-12-17 02:37:33

标签: java concurrency

我对以下几段代码感到困惑:

@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);
    }

}

据我所知,foreach之后的行System.out.println(..)应该只被调用一次。 但是代码的输出正在跟随。

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

有人可以解释一下如何调用它两次吗? 由于shutdown(),我的第一个输出和第二个输出行之间的线程没有被执行。

5 个答案:

答案 0 :(得分:0)

你的方法是递归的,那么为什么你不希望它被反复调用(每个目录一次)?

答案 1 :(得分:0)

在检查each是否是目录之后有一个递归调用,即 -

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

因此,如果(并且仅当)存在子目录,您将获得多行。

答案 2 :(得分: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

答案 3 :(得分:0)

你必须搬家

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

explore之外

当目录上执行的代码只包含文件时,将执行上述3行代码。并且因为您关闭了池,您将无法浏览所有文件。

答案 4 :(得分: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(..)方法来解决它。谢谢。