Pregunta

Tengo código que tiene que hacer algo como esto

Hay una lista de clases de cada uno con algún método (digamos que ejecutar ()). Necesito para invocar ese método en cada clase y hay un tiempo de espera fijo para cada invocación. Ahora, uno de método de ejecución de la clase está mal escrita y da como resultado un tiempo de espera debido a la que la JVM no sale. Me postulo la clase como esta.

java ExecutorServiceTest execute TestClass1 TestClass2 TestClass3

¿Por qué la JVM no de salida después de completar la ejecución del código?

Me da la siguiente salida

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)

La segunda clase de ejecutar el tiempo de espera y después de eso, de la tercera clase ejecutar también el tiempo de espera. ¿Por qué de la tercera clase ejecutar el tiempo de espera?

La JVM no sale después de la ejecución se ha completado. ¿Cual es la razon? También ¿por qué el TestClass3 ejecutar timedout?

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");
    }
}
¿Fue útil?

Solución

ExecutorService.shutdown() en realidad no deja de correr cualquier ejecutores / hilos, simplemente indica al servicio de no aceptar nuevas tareas :

  

void shutdown()
  Inicia un apagado ordenado en el que se ejecutan las tareas presentadas anteriormente, pero no se aceptarán nuevas tareas. Invocación no tiene ningún efecto adicional si ya se cerró.

La instancia TestClass2 nunca va a dejar de funcionar debido a que tiene un bucle while(true) que nunca se detuvo.

Si desea detener la ExecutorService de inmediato, puede utilizar awaitTermination(long timeout, TimeUnit unit) o shutdownNow().

Otros consejos

Es necesario llamar executor.shutdown() o crear un hilo de utilidad (usando ThreadFactory apropiada pasado a Executors.newSingleThreadExecutor()

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top