2012-01-17 10 views
12

¿Hay alguna manera de interrumpir un futuro sin cancelarlo?Concurrencia: interrumpir un futuro sin cancelarlo

java doc API:

booleano cancelar (booleano) mayInterruptIfRunning

intentos para cancelar la ejecución de esta tarea. Este intento fallará si la tarea ya se completó , ya se ha cancelado o no podría ser cancelada por algún otro motivo. Si tiene éxito, y esta tarea no se ha iniciado cuando se invoca cancel, esta tarea nunca debería ejecutarse. Si la tarea ya ha comenzado, entonces el parámetro mayInterruptIfRunning determina si el hilo que ejecuta esta tarea debe ser interrumpido en un intento de detener la tarea.

Para capturar la interrupción, debemos capturar apropiadamente la Excepción interrumpida o verificar el método isInterrupted() dentro del método Runnable/Callable.

Pero no hay manera de interrumpir un Futuro está ejecutando con la interfaz de futuro

Dado que todos los hilos están en la piscina Servicio Ejecutor, nadie puede hacer thread.interrupt(). ¿Es por eso que se ha asumido que cualquier interrupción vendrá solo cuando se cancela un futuro o termina un grupo de subprocesos?

Estoy tratando de entender por qué no hay un método de interrupción en la interfaz de Future. Cualquier ayuda será muy apreciada

+1

Me pregunto cuál sería el punto de esto ... es una pregunta interesante, si no es que extraña. –

+5

debido a algunos problemas. 1.) interrumpir es un riesgo, nunca se sabe cuándo o cuándo se puede interrumpir la tarea, 2.) El futuro no está vinculado a ningún hilo. Interrumpir el hilo de Future podría hacer quebrar otros futuros, 3.) Utilizando el mecanismo de cancelación, estás evitando uno de los errores más comunes relacionados con las carreras y el bloqueo, 4.) obtienes una gran garantía de que tu código no se detendrá de forma aleatoria. estado. – Rekin

+0

"Un futuro representa el resultado de un cálculo asincrónico": ¿no sería peligroso interrumpir una entidad asincrónica ya que el hilo de llamada puede continuar funcionando y está esperando recibir noticias de la entidad asincrónica? –

Respuesta

7

La razón se debe a la diferencia en la abstracción que es un futuro y la ejecución concreta en un hilo. No podemos decir si un futuro está vinculado a un solo hilo o hilo múltiple. Un futuro puede iniciar nuevos hilos, iniciar nuevos futuros, etc.

Considere estas abstracciones como interacciones entre el código del cliente y el ejecutor de los futuros. Conceptualmente, tiene sentido decir "cancelar esta tarea que te pedí que hagas" porque era tu tarea cancelarla. Puede que esté ocupado trabajando en eso, o puede que aún no lo haya comenzado, o puede que esté terminado, pero está bien, lo cancelaré si así lo desea. Entonces, es por eso que tenemos un método de cancelación.

Por otro lado, no tiene tanto sentido decir "interrumpa su tarea". Debido al desacoplamiento entre el resultado de la acción (el futuro) y el modelo de ejecución (por ejemplo, un ejecutor), el cliente no tiene conocimiento de las acciones que se están llevando a cabo para cumplir con la tarea. Entonces, ¿cómo se puede esperar que el cliente sepa cuándo una interrupción es apropiada, requerida o incluso compatible?

+1

http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html - Una interrupción es una indicación a un hilo de que debe detener lo que está haciendo y hacer algo más. Depende del programador decidir exactamente cómo responde un hilo a una interrupción, pero es muy común que el hilo termine. Pero en caso de Futuro, interrupción significa terminación. Acepto que, independientemente de lo que se pueda hacer con la interrupción, el futuro tendrá que hacerlo solo, como esperar una condición. Pero no estoy de acuerdo con que interrumpir un futuro no tenga sentido; las complejidades pueden no valer sin embargo – AKSG

0

En cualquier caso, puede utilizar un tiempo de espera, por lo que interrumpe su espera.

get(long timeout, TimeUnit unit) 
+0

Usted interrumpe la espera en el hilo de la persona que llama de hecho, pero no hay ningún hilo que ejecute la lógica para obtener el resultado de Future. Existe un interesante [Desafío de codificación: semántica de resultados parciales] (http://beust.com/weblog/2014/05/24/coding-challenge-partial-results-semantics/) que se relaciona con la interrupción del hilo para obtener un resultado parcial . –

0

Hay utilcases útiles para hacer esto.

Dado que el problema con la API futura es que no proporciona la capacidad para detectar que la ejecución se ha detenido. isCancelled() y isDone() ambos se devolverán correctamente aunque la ejecución del Callable continúe.

Por lo tanto, realmente no se trata del nivel de abstracción de la Future API en esta etapa. Pero es incapaz de identificar la finalización de la tarea. O para decirlo de otra manera, es la imposibilidad de diferenciar entre una solicitud de cancelación y una cancelación completa acción.

Una solución temporal es usar un CountdownLatch como se hace en la pregunta Waiting for a cancelled future to actually finish. Esto le indicará a la persona que está esperando que la tarea ya está hecha, y no solo le indicará que se detenga.

Cuestiones relacionadas