Ho letto su ThreadLocal, cercando di capire come funziona e perché ne abbiamo bisogno.ThreadLocal pondering (Oppure: javadoc del sole è sbagliato?)
Finora quello che ho potuto imparare è la seguente:
- classe ThreadLocal permette di tenere 1 istanza di un oggetto a livello di thread
- L'istanza viene creato sovrascrivendo initialValue()
- l'istanza viene effettivamente memorizzato nell'esempio utilizzo each thread's HashMap
- Un buon senso can be found here
Tutto sembrava bene, fino a quando ho provato a eseguire l'esempio dal javadoc, il codice viene fornito come segue:
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
Se ho capito questo codice correttamente, chiamando GetCurrentThreadId() dovrebbe restituire l'auto incrementato numero di thread corretto , purtroppo restituisce 0 per me. SEMPRE 0, senza considerare il numero di thread che ho avviato.
per ottenere questo lavoro per me ho dovuto cambiare GetCurrentThreadId() per leggere
public static int getCurrentThreadId() {
return uniqueId.get();
}
In questo caso sto ottenendo valori corretti.
Il mio codice è fornito di seguito, cosa mi manca? (Non è che il javadoc in realtà è sbagliato, giusto ??)
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
uscita:
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. Codice commenti OT o al punto sono i benvenuti nei commenti.
Incredibile, questo bug è quasi 4 anni. Ci vogliono 4 anni per correggere un refuso del manuale html su un server web. Nel frattempo c'erano 20 versioni di aggiornamento. Incredibile .... –
@Peter Le specifiche non possono essere modificate in una versione di aggiornamento. Puoi vedere che il bug è stato effettivamente corretto anni fa. –
Grazie per l'avviso. –