I've been reading about ThreadLocal, trying to understand how it works and why we need it.
So far what I've been able to learn is the following:
- ThreadLocal class allows to hold 1 instance of an object at the thread level
 - The instance is created by overriding initialValue()
 - The instance is actually stored in the each thread's HashMap
 - A common sense usage example can be found here
 
All seemed fine, until I tried to run the example from the javadoc, the code is provided as following:
 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
If I understand this code correctly, calling getCurrentThreadId() should return the correct auto incremented thread number, alas it returns 0 for me. ALWAYS 0, without consideration of how many threads I have started.
To get this working for me I had to change getCurrentThreadId() to read
     public static int getCurrentThreadId() {
         return uniqueId.get();
     } 
In which case I am getting correct values.
My code is provided below, what am I missing? (It's not that the javadoc is actually wrong, right??)
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
Output:
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. Code comments OT or to the point are welcome in comments.