Почему в этом случае JVM не завершается?

Я думаю, что в моем коде есть утечка потока, но я не уверен, почему. Вот код -

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 не умирает. Я должен вручную завершить его. хотя не понимаю почему...


person David says Reinstate Monica    schedule 08.07.2013    source источник
comment
Пожалуйста, покажите нам исполняемый код.   -  person Sotirios Delimanolis    schedule 08.07.2013
comment
@SotiriosDelimanolis Я показал вам весь соответствующий код.   -  person David says Reinstate Monica    schedule 08.07.2013
comment
Пожалуйста, покажите нам компилируемый и исполняемый код. Если это псевдокод, обязательно укажите его.   -  person Sotirios Delimanolis    schedule 08.07.2013
comment
@SotiriosDelimanolis Я думал, что это было самоочевидно, учитывая тот факт, что нет возвращаемого типа, у получателей нет попытки/пойма вокруг них, и у меня есть небольшой рабочий комментарий .... И даже только это было достаточно, чтобы решить мою проблему. Полный файл не нужен.   -  person David says Reinstate Monica    schedule 08.07.2013


Ответы (3)


проблема в том, что когда я нажимаю FileNotFoundException

Когда вы сталкиваетесь с этим исключением, кажется, что ваш обработчик исключений не отключает ExecutorService. Если вы не остановите ExecutorService, этот пул потоков останется там.

person kosa    schedule 08.07.2013
comment
Ах да, я забыл это сделать. Я просто отключил один в конце и решил, что этого достаточно. - person David says Reinstate Monica; 08.07.2013

Используйте блок 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 никогда не возвращается нормально.

person Brian    schedule 08.07.2013

Исключение генерируется в отдельном потоке. Поток, порожденный в es.call(), должен умереть, но не основной поток (или поток, выполняющий foo()). И JVM все еще работает, потому что основной поток не умер.

person evanwong    schedule 08.07.2013