为什么JVM在这种情况下不会终止?

时间:2013-07-08 19:08:04

标签: java eclipse multithreading jvm resource-leak

我想我的代码中有一个线程泄漏,但我不确定原因。这是代码 -

foo(String solutionFileName, String SubmissionFileName){
    ExecutorService e = Executors.newFixedThreadPool(
    Future<BufferedReader> f1 = e.submit(new Builder(solutionFileName));
    Future<BufferedReader> f2 = e.submit(new Builder(submissionFileName));
    BufferedReader b1=f1.get();
    BufferedReader b2=f2.get();
    //do a little work
    e.shutdown();
}

class Builder{
    Builder(String fileName){this.fileName=fileName;}
    public BufferedReader call() throws FileNotFoundException{
        return new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
    String fileName;
    }
}

我在Eclipse上运行它,问题是当我遇到FileNotFoundException时,JVM不会死。我必须手动终止它。我不明白为什么......

3 个答案:

答案 0 :(得分:4)

  

问题是当我遇到FileNotFoundException

当您点击此异常时,您的异常处理程序似乎没有关闭ExecutorService。如果您不关闭ExecutorService,该线程池将保留在那里。

答案 1 :(得分:1)

使用try / finally块:

ExecutorService e = Executors.newFixedThreadPool(10);
try {
    Future<BufferedReader> f1 = e.submit(new Builder(solutionFileName));
    Future<BufferedReader> f2 = e.submit(new Builder(submissionFileName));
    BufferedReader b1=f1.get();
    BufferedReader b2=f2.get();
    //do a little work
} finally {
    e.shutdown();
}

无论退出shutdown块如何,都会导致try调用被执行。您的代码抛出异常,导致跳过e.shutdown()行(异常通常会导致所有代码执行停止)。通过添加finally,您可以保证无论try块如何退出,都会调用e.shutdown()

有一个例外。如果你这样做:

try {
    System.exit(0);
} finally {
    System.out.println("Finally block");
}

"Finally Block"永远不会被打印,因为System.exit永远不会正常返回。

答案 2 :(得分:0)

异常在一个单独的线程中抛出。 es.call()中生成的线程应该死掉,但不是主线程(或运行foo()的线程)。 并且JVM仍在运行,因为主线程没有死亡。