2012-02-20 25 views
5

hice la siguiente error:¿Hay alguna manera de hacer que un ExecutorService funcione recursivamente?

  1. Llamado Executors.newFixedThreadThreadPool para hacer una piscina
  2. Establecer una lista de Callable objetos, de tal manera que el método call a su vez trató de iniciar una tarea en la misma piscina hilo
  3. volcará en la cola con invokeAll

los resultados fueron un punto muerto en la cola de la executo r servicio.

El Javadoc que he leído no parece prohibir este conjunto de actividades. ¿Me he perdido algo? ¿Hay alguna manera de personalizar la cola o el servicio para que esto funcione?

+0

Yo tenía una pregunta similar. Digamos que mi grupo de subprocesos solo tiene un único subproceso. Mi Callable externo obtiene el hilo e invoca una subtarea Llamada. Luego espera a que se complete la subtarea. Sin embargo, dado que el único subproceso del grupo ya está asociado a la tarea externa, nunca se asignará a la tarea interna, lo que provocará un interbloqueo. ¿Es correcta esta evaluación o me falta algo? –

+0

Después de pensar en esto un poco más, parece que podría entrar en un punto muerto si el número de ramas (es decir, el número de tareas que generan subtareas) es mayor que el número de subprocesos en el grupo. Por lo tanto, cuando el recuento de sucursal supera el recuento de subprocesos, puede ejecutar las subtareas en serie en lugar de enviarlas para su ejecución en paralelo. No lo he intentado pero conceptualmente parece que debería funcionar. –

Respuesta

3

Mi comprensión de su pregunta es algo así como el siguiente caso de prueba, que funciona como está documentado (como usted dice) y lo he utilizado felizmente en la producción. ¿Cómo difiere tu ejemplo de esto?

import java.util.Date; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

class Scratch { 
    public static void main(String[] args) throws InterruptedException { 
     final ExecutorService pool = Executors.newFixedThreadPool(1); 
     pool.submit(new Callable<Void>() { 
      @Override 
      public Void call() throws Exception { 
       pool.submit(new Callable<Void>() { 
        @Override 
        public Void call() throws Exception { 
         System.out.println(new Date() + ": Second callable being run."); 
         pool.shutdown(); 
         return null; 
        } 
       }); 

       System.out.println(new Date() + ": First callable going to sleep..."); 
       Thread.sleep(2000); 
       System.out.println(new Date() + ": First callable finished!"); 
       return null; 
      } 
     }); 

     pool.awaitTermination(2, TimeUnit.MINUTES); 
    } 
} 

imprime algo como:

Mon Feb 20 01:18:00 GMT 2012: First callable going to sleep... 
Mon Feb 20 01:18:02 GMT 2012: First callable finished! 
Mon Feb 20 01:18:02 GMT 2012: Second callable being run. 
+0

Mi función externa es usar pool.invokeAll, no pool.submit, por lo que está esperando. Y ahora sospecho que el problema es que todos los hilos se utilizan en los hilos "externos", por lo que no se trabaja dentro. En otras palabras, yo era un idiota. – bmargulies

+0

Aun así, una ejecución ejecutable debería ser capaz de 'enviar()' una nueva llamada (como 'submit()' nunca se bloquea en '' newFixedThreadPool() ')? A menos que estuvieras usando 'pool.invokeAll()' dentro de los Callables también? – FauxFaux

+0

Eso está dentro de lucene y no sé. Pero si todos los hilos se usaron por fuera, el interior puede enviarse, pero nunca progresar, y ninguno de los exteriores se completará tampoco. – bmargulies

Cuestiones relacionadas