He estado leyendo acerca de ThreadLocal, tratando de entender cómo funciona y por qué lo necesitamos.reflexión de ThreadLocal (¿o es incorrecto el javadoc de sun?)
Hasta ahora lo que he sido capaz de aprender es la siguiente:
- clase ThreadLocal permite mantener 1 instancia de un objeto en el nivel de rosca
- La instancia se crea reemplazando initialValue()
- la instancia se almacena en el ejemplo de uso each thread's HashMap
- un sentido común can be found here
Todo parecía estar bien, hasta que intentó ejecutar el ejemplo de la javadoc, se proporciona el código de la siguiente manera:
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal <Integer> uniqueNum =
new ThreadLocal <Integer>() {
@Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueId.get();
}
} // UniqueThreadIdGenerator
Si entiendo este código correctamente, llamando GetCurrentThreadId() debería devolver el número de hilos automático incrementado correcta , por desgracia, devuelve 0 para mí. SIEMPRE 0, sin considerar cuántos hilos he comenzado.
Para conseguir este trabajo para mí que tenía que cambiar GetCurrentThreadId() para leer
public static int getCurrentThreadId() {
return uniqueId.get();
}
En cuyo caso, que estoy recibiendo valores correctos.
Mi código se proporciona a continuación, ¿qué es lo que me falta? (No es que el Javadoc es realmente mal, no ??)
package org.vekslers;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class UniqueThreadIdGenerator extends Thread {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
private static final ThreadLocal <Integer> uniqueNum =
new ThreadLocal <Integer>() {
@Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueNum.get();
}
//////////////////////////////////////////////////
// Testing code...
//////////////////////////////////////////////////
private static volatile boolean halt = false;
public UniqueThreadIdGenerator(String threadName) {
super(threadName);
}
@Override
public void run() {
System.out.println(Thread.currentThread() + " PREHALT " + getCurrentThreadId());
while(!halt)
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread() + " POSTHALT " + getCurrentThreadId());
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new UniqueThreadIdGenerator("t1");
Thread t2 = new UniqueThreadIdGenerator("t2");
Thread t3 = new UniqueThreadIdGenerator("t3");
Thread t4 = new UniqueThreadIdGenerator("t4");
t3.start();
t1.start();
t2.start();
t4.start();
TimeUnit.SECONDS.sleep(10);
halt = true;
}
} // UniqueThreadIdGenerator
Salida:
Thread[t3,5,main] PREHALT 0
Thread[t1,5,main] PREHALT 1
Thread[t2,5,main] PREHALT 2
Thread[t4,5,main] PREHALT 3
Thread[t4,5,main] POSTHALT 3
Thread[t2,5,main] POSTHALT 2
Thread[t1,5,main] POSTHALT 1
Thread[t3,5,main] POSTHALT 0
P. S. Comentarios del código OT o al punto son bienvenidos en los comentarios.
increíble, este error es casi 4 años de edad. Se necesitan 4 años para corregir un error tipográfico del manual html en un servidor web. Mientras tanto, hubo 20 lanzamientos de actualización. Increíble .... –
@ Peter La especificación no se puede cambiar en una versión de actualización. Puedes ver que el error fue arreglado hace años. –
Gracias por el aviso. –