J'ai lu ThreadLocal, essayant de comprendre comment cela fonctionne et pourquoi nous en avons besoin.ThreadLocal songering (Ou: Le javadoc du soleil est-il faux?)
Jusqu'à présent, ce que je suis en mesure d'apprendre est le suivant:
- classe ThreadLocal permet de tenir une instance d'un objet au niveau du fil
- L'instance est créée en remplaçant initialValue()
- l'instance est stocké dans le each thread's HashMap
- Un usage bon sens exemple can be found here
Tout semblait bien, jusqu'à ce que j'ai essayé de courir l'exemple de la javadoc, le code est fourni ci-dessous:
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 je comprends ce code correctement, appelant GetCurrentThreadId() renvoie le nombre de threads incrémentée de correction automatique , hélas ça revient 0 pour moi. TOUJOURS 0, sans tenir compte du nombre de threads que j'ai démarré.
Pour obtenir ce travail pour moi que je devais changer GetCurrentThreadId() pour lire
public static int getCurrentThreadId() {
return uniqueId.get();
}
Dans ce cas, je recevais des valeurs correctes.
Mon code est fourni ci-dessous, que manque-t-il? (Ce n'est pas que le javadoc est en fait mal, droit ??)
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
Sortie:
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. Les commentaires de code OT ou au point sont les bienvenus dans les commentaires.
Incroyable, ce bug est près de 4 ans. Il faut 4 ans pour corriger une faute de frappe du manuel html sur un serveur web. Entre-temps, il y a eu 20 mises à jour. Incroyable .... –
@Peter La spécification ne peut pas être modifiée dans une version de mise à jour. Vous pouvez voir que le bug a été corrigé il y a des années. –
Merci pour l'avis. –