2010-01-06 29 views
8

Estoy buscando una clase similar a ThreadLocal que funcione en grupos de hilos en lugar de hilos.¿Hay variables locales de grupos de subprocesos en Java?

Si no existe tal clase (en alguna biblioteca de código abierto) ¿cómo la implementaría? ¿Alguna idea mejor que tener grupos de subprocesos en WeakHashMap?

Estoy implementando un marco de depuración optimizable en tiempo de ejecución con varios parámetros en contextos globales, por subproceso y por grupo de subprocesos. Como un ejemplo muy simple, puede tener una declaración de informes:

debug.log(category, message); 

y especificar que la entrada de registro con esa categoría específica se mostrará sólo cuando es llamado por un hilo en el grupo de hilos están sirviendo peticiones de red.

+1

Para mayor claridad, es posible que desee arrojar algunos ejemplos de uso. También por qué/cómo quieres hacer esto. –

+0

@Kevin: Acabo de agregar una motivación y un simple ejemplo. – Viliam

Respuesta

4

Guardaría un soporte de valor en un subproceso local e lo inicializaría en el mismo soporte de valor para todos los subprocesos del mismo grupo.

public class ThreadGroupLocal<T> extends ThreadLocal<ValueHolder> { 
    private static class ValueHolder { 
     public Object value; 
    } 
    // Weak & Concurrent would be even the better, but Java API wont offer that :(
    private static ConcurrentMap<ThreadGroup, ValueHolder> map = new ConcurrentHashMap<ThreadGroup, ValueHolder>; 
    private static ValueHolder valueHolderForThread(Thread t) { 
     map.putIfAbsent(t.getThreadGroup(), new ValueHolder()); 
     return map.get(t.getThreadGroup()); 
    } 
    @Override 
    protected ValueHolder initialValue() { 
     return valueHolderForThread(Thread.currentThread()); 
    } 
    public T getValue() { (T) get().value; } 
    public void setValue(T value) { get().value = value; } 
} 

y luego usar

ThreadGroupLocal<String> groupLocal = new ThreadGroupLocal<String>(); 
groupLocal.setValue("foo"); 
//... 
String foo = groupLocal.getValue(); 

Eso no (esperar para la inicialización) realizan exactamente igual que una secuencia de procesamiento local.

+0

¿Por qué no generó ValueHolder? ¿Y por qué lo hiciste ampliar ThreadLocal? El uso de ThreadLocal es un detalle de implementación. –

+0

Buenos puntos, valen la pena ser considerados. Escribí ese código a toda prisa como prueba de concepto, así que por favor revisen (¡y prueben!) Antes de usarlo en producción. (PD: * Recuerdo ahora por qué ValueHolder no está genérico, porque están almacenados en un mapa hash estático que degeneraría en '', por lo que debe emitir de todos modos.*) – akuhn

+0

+1, Justo lo que estaba buscando. ¿Sabes si en la actualidad la API de Java admite de forma nativa esta función? – dreamcrash

2

La última vez que miré la implementación (bueno hace unos años) Thread Locals se implementaron como una simple tabla hash indexada por el id. De subproceso. Nada lujoso y lejos de la eficiencia de C++.

Puede hacer lo mismo y usar el objeto del grupo de hilos como una clave para su propia tabla de hash de locales del grupo de hilos.

+0

Even (Sun) 1.2 se ha actualizado para no hacer eso. Es muy ineficiente. –

+0

Sí, sé que fue hace mucho tiempo. – Lothar

+0

Creo que ahora es una tabla hash dentro de la instancia Thread, indexada por el objeto ThreadLocal. Esto elimina la sobrecarga de sincronización, una tabla hash privada por subproceso. – Thilo

5

ThreadGroup se usa raramente, por lo que no hay soporte de plataforma.

Utilizando [Weak/Identity/Concurrent] HashMap<ThreadGroup,T> se trata sólo de trabajo, si no es muy rápido. Realmente quieres que el mapa sea todo débil, identidad y concurrente, pero con la biblioteca Java solo puedes elegir uno, actualmente.

Para mejorar el rendimiento, tenga en cuenta que Thread s no cambian ThreadGroup. Por lo tanto, guarde en caché el valor con ThreadLocal (anule initialValue). ThreadLocal tiene un buen rendimiento (un par de docenas de ciclos por get).

+0

Buen truco de rendimiento, gracias. – Viliam

+0

+1, por los problemas de rendimiento. ¿Sabes si en la actualidad la API de Java admite de forma nativa esta función? – dreamcrash

Cuestiones relacionadas