2012-05-04 15 views
6

Por lo que yo puedo entender a partir de los documentos java.lang.Thread, y de otras preguntas publicadas aquí en stackoverflow, como "How to access a Runnable object by Thread?" y "Get current instance of Runnable" No es posible obtener una referencia del objeto incrustado en un RunnableThread.¿Por qué no se puede incrustar Runnable en un subproceso?

Un escenario donde tener esta posibilidad sería útil es cuando se implementa un método, cuya firma no se puede modificar porque estamos anulando un método definido en otra clase o interfaz, y se requieren diferentes operaciones según el tipo de Runnable incrustado en la corriente Thread.

Si tenemos, por ejemplo, un método llamado getRunnable en la clase Thread podríamos hacer algo como esto:

if (Thread.currentThread().getRunnable() instanceof Type1) { 
    // do something... 
} else { 
    // do something else... 
} 

Esto podría ser útil también en situaciones en las que queremos garantizar las operaciones contenidas en un método son ejecutado solo por ciertos hilos y no por otros.

Entonces, me preguntaba, ¿hay alguna razón específica por la que los desarrolladores de Java decidieron no permitir la instancia Runnable de Thread, o es una característica faltante que vale la pena notificar? Si cree que no hay razón detrás de esa elección, pero no vale la pena notificarla como característica faltante, ¿qué estrategia usaría en el escenario descrito anteriormente?

+0

¿Cuál sería el "ejecutable" para el hilo principal con el método 'main'? –

+2

@KirkWoll, 'null'? –

+4

La ramificación en el resultado de 'instanceof' como lo hace en su ejemplo casi nunca es una buena idea. – NPE

Respuesta

11

Así que me preguntaba, ¿hay una razón específica por la cual los desarrolladores de Java decidieron no permitir que para obtener la instancia Ejecutable de un hilo

Fue probablemente sólo no es un requisito. El Runnable debería ser capaz de identificar su propia clase, por lo que la idea de que necesita obtener esa información es extraña. También podría ser una protección para que otros subprocesos no tengan acceso a la clase que se está ejecutando en otro subproceso.

Si necesita acceder a la actual Runnable desde otras partes de su aplicación, le recomiendo usar ThreadLocal<Runnable>. En su método run(), puede configurarlo y luego recuperarlo en sus otras clases. Sin embargo, necesitaría poner el ThreadLocal en algún lugar accesible globalmente.

También podría procesar la traza de la pila actual para descubrir la clase Runnable que es aún más un hack pero funcionaría.

5

Hay un par se acerca usted podría tomar para evitar esto:

Mantener un mapeo de sus Runnable s de los Thread s de que ellos están ejecutando (ya sea con un Map<Thread, Runnable> o con un ThreadLocal<Runnable>)
utilizar la reflexión para acceder a la Runnable del Thread:

private static final Field target; 
static { 
    Field f = null; 
    try { 
     f = Thread.class.getDeclaredField("target"); 
     f.setAccessible(true); 
    } catch (NoSuchFieldException e) { 
     // might happen in a different version of Java (works in Java 7) 
     e.printStackTrace(); 
    } 
    target = f; 
} 

public static Runnable getTarget(Thread t) { 
    try { 
     return (Runnable) target.get(t); 
    } catch (IllegalAccessException e) { 
     // shouldn't happen, we already made the field accessible when we created it 
     e.printStackTrace(); 
     } 
    return null; 
} 
0

Hay un método indirecto puede ser que ayudará, Usted puede obtener el seguimiento de la pila.

StackTraceElement[] stackTraceElement = thread.getStackTrace(); 
for(StackTraceElement e :stackTraceElement){ 
    System.out.println("Trace "+e.getClassName()); 
} 

Salida:

traza java.lang.Hilo

traza com.emc.multithreading.RunnableDemo

traza java.lang.Thread

Cuestiones relacionadas