2012-04-06 9 views
8

Creo un ThreadPool con 10 hilos fijos en él. A veces tengo que interrumpir un hilo longrunning en el grupo de subprocesos, sobre todo porque están bloqueando en alguna operación y se produce un tiempo de espera e interrumpo el hilo. Cojo el InterruptedException y configuro el estado del Thread para interrumpirlo también. En ese caso, mi pregunta es, ¿ThreadPool crea un nuevo hilo y reemplaza el hilo interrumpido por uno nuevo? A continuación se muestra el código de ejemplo que se ejecuta con el subproceso. La pregunta es, cuando este hilo se interrumpe, ¿el grupo de hilos reemplaza este hilo por uno nuevo?cómo el ejecutor del conjunto de Java thead trata con el hilo interrumpido

public ResponseMessage call(){ 
    Future<ResponseMessage> future = CacheManager.getInstance().asyncFetch(); 
    ResponseMessage response = null; 
    try { 
     response = future.get(); 
    } 
    catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } catch (ExecutionException ex) { 
     //create a blank response 
    } 

    return response; 
} 
+2

qué tipo de subprocesos está usando? – dash1e

+1

Usted sabe que 'get()' tiene una sobrecarga que acepta un tiempo de espera, ¿verdad? – erickson

+0

¿Qué hace 'StopWatch'? – erickson

Respuesta

7

No debe interrumpir los hilos que no es "suyo", porque no sabe cómo responden. Como no tiene control sobre la programación de hilos, realmente no sabe que un hilo determinado está ejecutando una tarea en particular en el instante en que lo interrumpe

Si desea cancelar una tarea que le ha asignado a un ejecutor servicio, llame al cancel(true) en su asociado Future. Cuando su tarea detecta una solicitud de interrupción, debe preservar el estado interrumpido llamando al Thread.currentThread().interrupt().

Si hace esto, el ejecutor manejará la interrupción limpiamente porque interrumpió el hilo en sí, y sabe que el hilo estaba ejecutando una tarea cuando se produjo la interrupción.

+0

Estoy siguiendo exactamente como usted mencionó, cancelo el futuro y en el hilo de llamada, preservo el estado de la interrupción. – Shamik

+1

@Shamik No veo ninguna llamada a 'cancelar()' en su código. – erickson

+0

Hay un llamante del código anterior, que envía esta tarea invocable al grupo de subprocesos y cancela la tarea utilizando future.cancel (true) – Shamik

0

De la depuración paso a paso, supongo que el hilo interrumpido continuará obteniendo la tarea de la cola de trabajo. El estado de interrupción ya se limpió antes de getTask.

Por ejemplo, si está utilizando FixedThreadPool con LinkedBlockingQueue, el estado interrumpida se limpia el interior de queue.take() por ReentrantLock.lockInterruptibly()

public final void acquireInterruptibly(int arg) throws InterruptedException { 
    if (**Thread.interrupted()**) 
     throw new InterruptedException(); 
    if (!tryAcquire(arg)) 
     doAcquireInterruptibly(arg); 
} 
Cuestiones relacionadas