JVM не завершает работу при возникновении исключения TimeoutException

StackOverflow https://stackoverflow.com/questions/2419611

Вопрос

У меня есть код, который должен сделать что-то вроде этого

Существует список классов, каждый из которых имеет какой-либо метод (скажем, выполнение()).Мне нужно вызвать этот метод для каждого класса, и для каждого вызова существует фиксированное время ожидания.Теперь один из методов выполнения класса написан плохо и приводит к тайм-ауту, из-за которого jvm не завершается.Я провожу урок вот так.

java ExecutorServiceTest execute TestClass1 TestClass2 TestClass3

Почему jvm не завершает работу после завершения выполнения кода?

Я получаю следующий вывод

In class 1
In Class 2
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at ExecutorServiceTest.main(ExecutorServiceTest.java:78)
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)

Время выполнения второго класса истекает, а после этого время выполнения третьего класса также истекает.Почему время выполнения третьего класса истекает?

JVM не завершает работу после завершения выполнения.Какова причина?Также почему TestClass3 выполнить таймаут?

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

class Task implements Callable<String> {
    Object instance;
    Method m;
    Object[] input;
    Task(Object instance, Method m, Object[] input) {
        this.instance = instance;
        this.m = m;
        this.input = input;
    }
    public String call() {
        String s = "initial";
        try {
            m.invoke(instance, input);
        }
        catch (RuntimeException e) {
        }
        catch (Exception e) {
        }
        finally {

        }
        return s;
    }
}


public class ExecutorServiceTest {
    public static void main(String[] args) {
        String methodName = args[0];
        String className;
        List<Object> instanceList = new ArrayList<Object>();
        for (int i=1;i<args.length;i++) {
            className = args[i];
            Object o = null;
            try {
                o = Class.forName(className).newInstance();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            instanceList.add(o);
        }
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Iterator<Object> iter = instanceList.iterator();
        while (iter.hasNext()) {
            Object o = iter.next();
            Method m = null;
            try {
                m = o.getClass().getDeclaredMethod(methodName, new Class[] {});
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Task t = new Task(o,m,new Object[]{});
            Future<String> fut = executor.submit(t);
            try {
                fut.get(2,TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (TimeoutException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        executor.shutdown();
    }
}


public class TestClass1 {
    public void execute() {
        System.out.println("In class 1");
    }
}


public class TestClass2 {
    public void execute() {
        System.out.println("In class 2");
        boolean b = true;
        while (b) {

        }
    }
}


public class TestClass3 {
    public void execute() {
        System.out.println("In class 3");
    }
}
Это было полезно?

Решение

ExecutorService.shutdown() фактически не останавливает работающие исполнители/потоки, он просто сообщает службе прекратить принимать новые задачи:

void shutdown()
Инициирует упорядоченное завершение работы, при котором ранее отправленные задачи выполняются, но новые задачи приниматься не будут.Вызов не имеет дополнительного эффекта, если он уже выключен.

Ваш экземпляр TestClass2 никогда не перестанет работать, потому что у него есть while(true) цикл, который никогда не останавливается.

Если вы хотите немедленно остановить ExecutorService, вы можете использовать awaitTermination(long timeout, TimeUnit unit) или shutdownNow().

Другие советы

Вам нужно позвонить executor.shutdown() или создайте поток демона (используя соответствующий ThreadFactory перешел к Executors.newSingleThreadExecutor()

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top