2011-09-13 11 views
7

Tengo una pregunta acerca de Java y concurrencia.Java Grupo de subprocesos en caché y subprocesos local

Digamos que tengo una variable ThreadLocal llamada a. Y utilizo CachedThreadPool para obtener nuevos hilos. Cuando se vuelve a ejecutar un hilo, ¿qué pasa con la variable ThreadLocal? Mantiene el mismo valor (porque es el mismo hilo) o comienza vacío (como si el hilo fuera nuevo)?

Gracias

Respuesta

10

De manera predeterminada, las ThreadLocals se vuelven a utilizar junto con la secuencia. Si los necesita para ser reinicializar puede hacerlo sobreescribiendo los métodos indicados a continuación:

from javadoc for java.util.concurrent.ThreadPoolExecutor

métodos Hook Esta clase proporciona protegida reemplazable BeforeExecute (java.lang.Thread, java. lang.Runnable) y afterExecute (java.lang.Runnable, java.lang.Throwable) métodos que se llaman antes y después de la ejecución de cada tarea. Estos se pueden usar para manipular el entorno de ejecución; por ejemplo, reiniciando ThreadLocals, recopilando estadísticas o agregando entradas de registro. Además, el método terminado() puede anularse para realizar cualquier procesamiento especial que deba realizarse una vez que el Ejecutor haya terminado por completo. Si los métodos hook o callback arrojan excepciones, los subprocesos internos de trabajo pueden a su vez fallar y terminar bruscamente.

+1

Un problema solucionable que veo aquí es que el ThreadPoolExecutor necesita conocer el hilo local. Tipo de mala separación. Puede ser resuelto por un observable que arroja un evento una vez que termina una ejecución. Un hilo local específico puede registrarse (observador) hacer una limpieza una vez que se dispara el evento afterExecute. –

3

Si el hilo se devuelve a la piscina, la variable ThreadLocal todavía se le atribuye. Al utilizar ThreadLocals con pools, debe tener cuidado de poder establecer cuándo se extrae el hilo del grupo y deshacerlo antes de que se devuelva.

2

Puede borrar el grupo local de subprocesos para un subproceso mediante reflexión. Usted puede hacer

public static void clearAllThreadLocals() { 
    try { 
     Field threadLocals = Thread.class.getDeclaredField("threadLocals"); 
     threadLocals.setAccessible(true); 
     threadLocals.set(Thread.currentThread(), null); 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 
} 
Cuestiones relacionadas