Pregunta

Tengo una larga tarea en ejecución, algo como:

public void myCancellableTask() {
    while ( someCondition ) {
       checkIfCancelRequested();
       doSomeWork();
    }
 }

La tarea puede ser cancelada (una cancelación se solicita y checkIfCancelRequested() comprueba que el indicador de cancelar).Generalmente cuando escribo cancelables bucles como este, yo uso una bandera para indicar que una cancelar se ha solicitado.Pero, sé que yo también podría usar Hilo.interrumpir y comprobar si el hilo ha sido interrumpida.No estoy seguro de cuál sería el enfoque preferido y por qué, los pensamientos?

gracias,

Jeff

¿Fue útil?

Solución

Interrupción arruinará el hilo de una lista de espera de las condiciones especificadas. Su propia cancelar la bandera no lo hará. Si desea interrumpir espera en IO y eventos, utilice interrupción. De lo contrario usar su cuenta.

Otros consejos

Un problema con el uso de la interrupción es que si usted no puede controlar todo el código que está siendo ejecutado, se corre el riesgo de la interrupción no funciona "correctamente" porque de alguien roto la comprensión de cómo manejar las interrupciones en su biblioteca.Que es la API de forma invisible las exportaciones de una API en torno a su manejo de interrupts que usted se convierte en dependiente.

En tu ejemplo, supongamos que doSomeWork fue en la 3ª parte FRASCO y se ve como:

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

Ahora usted tiene que manejar un AssertionError (o cualquier otra cosa que la biblioteca está utilizando podría lanzar).He visto los desarrolladores experimentados lanzar todo tipo de tonterías sobre la recepción de las interrupciones!Por otro lado, tal vez el método se veía así:

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

Este "mal manejo" de la interrupción provoca que el sistema en bucle indefinidamente.De nuevo, no rechaza esto como ridículo;hay un montón de rota manejo de la interrupción de los mecanismos de allí.

Al menos usando su propia bandera será completamente invisible para la 3ª parte de las bibliotecas.

Depende de la aplicación doSomeWork(). Es que el cálculo puro o lo hace (en cualquier momento) implican la oclusión de la API (tales como IO) llamadas? Por de bmargulies respuesta, muchas API de bloqueo en JDK son interrumpibles y se propagarán a excepción interrumpida hasta la pila.

Por lo tanto, si el trabajo implica el bloqueo de las actividades potencialmente, que need'll interrupciones para tomar en consideración incluso si que deciden controlar el proceso usando una bandera, y de manera apropiada debe capturar y manejar / propagar la interrumpe.

Más allá de eso, si se depende de una bandera, asegúrese de que el indicador se declara con la semántica volatile.

Creo que es una cuestión de preferencia en la mayoría de los casos. Personalmente me gustaría ir a por la bandera hecha a mano. Se le da más control - por ejemplo, esta manera se asegura que el hilo no sale de algún otro objeto en un estado incoherente. Además, si el rendimiento es realmente crítico, tener en cuenta que el uso de excepciones tiene una sobrecarga (aunque sea insignificante en el 99% de los casos).

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