¿Por qué ThreadPoolExecutor finaliza invoca el apagado y no el apagado ahora?

Finalizar método en clase ThreadPoolExecutor Se parece a continuación.

protected void finalize()  {
    shutdown();
}

Considere el siguiente programa en el que el hilo nunca termina

ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                new SynchronousQueue<String>()
                        .put("will never get removed");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    executorService = null;
    System.gc();

}

En tal caso shutdownNow Hubiera sido mejor elección que shutdown al menos JVM podría haber salido en ese caso.

Actualizar:

La única explicación posible de por qué finalize llamadas shutdown El método es que si el programador no lo llama explícitamente, se llamará mientras GC como mecanismo defensivo. Veo fallas en este mecanismo ya que en el caso anterior JVM no se terminará.

preguntado el 22 de septiembre de 12 a las 16:09

3 Respuestas

Primero, déjame hacerte una pregunta: ¿Por qué necesitarías agrupar un hilo que nunca termina? Juntas objetos para reutilizarlos.

La razón por la que java llama al apagado es para dar a los subprocesos la oportunidad de terminar correctamente.

Si necesita ejecutar un subproceso en un bucle infinito, entonces su subproceso debe verificar que Thread.currentThread().isInterrupted() devuelve falso, y luego regresa de run().

En el ejemplo que muestra, es posible que desee utilizar el método offer() con un tiempo de espera, más bien y put().

En el peor de los casos, puede extender ThreadPoolExecutor y llama shutdownNow() en el finalizador.

Respondido el 22 de Septiembre de 12 a las 17:09

Actualizada la pregunta. La pregunta es si es un mecanismo defensivo, ¿por qué se implementa de esa manera? - Amit Deshpande

No es realmente un mecanismo defensivo, es por lo que el ThreadPoolExecutor se comportaría como cualquier otro objeto java, y cuando no es accesible, le dice a los subprocesos que se detengan para que pueda ser recolectado como basura. - Agosto

La moraleja de esta historia es que si desea que un ThreadPool se apague, no debe depender de finalizar para hacerlo. Esto es cierto para cualquier recurso en Java, debe nunca depender del mecanismo de finalización (ya que puede nunca correr). si desea que un ThreadPool se apague, debe administrarlo usted mismo.

La shutdown() llamar al método finalize es un compromiso razonable en el caso de que un programador "accidentalmente" pierda el rastro de un ThreadPool. las tareas actuales se ejecutarán hasta completarse y luego el grupo se cerrará. si shutdownNow() se usaron, en algún momento aleatorio (dependiendo del gc), sus tareas se interrumpirían. probablemente menos que ideal. y tu puedes siempre crear una tarea que se niegue a cerrarse independientemente de si shutdown() or shutdownNow() es invocado (simplemente agregue un while(true) recorre el bloque try/catch en tu ejemplo).

Respondido el 22 de Septiembre de 12 a las 17:09

En el momento en que shutdown() se invoca, significa que el grupo no aceptará nuevas tareas y en realidad "cerrar" después de que se hayan realizado las tareas enviadas. Para su caso, será mejor que invoque shutdownNow() explícitamente en algún lugar que desee.

Respondido el 22 de Septiembre de 12 a las 17:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.