4 Replies Latest reply: Aug 19, 2009 8:39 AM by 782681 RSS

    ThreadLocal and the API doc

    843790
      Hi,

      I'm trying to understand ThreadLocal. The API javadoc provides the following example of a use of a ThreadLocal at http://java.sun.com/javase/6/docs/api/ :
      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
      However I'm not sure I get this right. As far as I can tell, uniqueId is not thread-local, and will return basically the number of threads (minus 1) that have been created at any point in time, for any thread (rather than a unique ID for each thread). Shouldn't it be
       public static int getCurrentThreadId() {
               return uniqueNum .get();
           }
      (ie uniqueNum rather than uniqueID)? I can't imagine this error not having been spotted earlier, but I've looked online and can't find anything about it. Is there some understanding I'm missing?

      Thanks,

      Lis
        • 1. Re: ThreadLocal and the API doc
          EJP
          As far as I can tell, uniqueId is not thread-local
          Correct. But the object returned by uniqueId.get() is thread-local.
          and will return basically the number of threads (minus 1) that have been created at any point in time, for any thread (rather than a unique ID for each thread).
          Nope. Try it.
          • 2. Re: ThreadLocal and the API doc
            843790
            Ok I'm not a big thread pro (if that wasn't clear already ; ) ), so I tested this best I could. I copied the test class of the API and renamed to ThreadLocalTest. I then ran the following main:
            public class ThreadLocalTestrun
            {
                 public static void main(String[] args)
                 {
                      System.out.println("at the start - " + ThreadLocalTest.getCurrentThreadId() + " - " + Thread.currentThread().getName());
            
                      new MyThread("NewThread-1").start();
                      new MyThread("NewThread-2").start();
            
                      System.out.println("in the end - " + ThreadLocalTest.getCurrentThreadId() + " - " + Thread.currentThread().getName());
                 }
            
                 public static class MyThread
                      extends Thread
                 {
                      String message;
            
                      MyThread(String name)
                      {
                           super(name);
                      }
            
                      @Override
                      public void run()
                      {
                           boolean hasRun = false;
                           while (!hasRun)
                           {
                                System.out.println("Current Thread Id: " + ThreadLocalTest.getCurrentThreadId() + " (name '" + Thread.currentThread().getName() + "')");
                                hasRun = true;
                           }
                      }
                 }
            }
            If I run the code with the uniqueId call, I get the following output:
            at the start - 0 - main
            in the end - 0 - main
            Current Thread Id: 0 (name 'NewThread-1')
            Current Thread Id: 0 (name 'NewThread-2')
            (and I don't understand why uniqueId hasn't been incremented except perhaps that uniqueNum never gets instantiated because it's not called?)

            I then ran it with uniqueNum instead and got this:
            at the start - 0 - main
            in the end - 0 - main
            Current Thread Id: 2 (name 'NewThread-1')
            Current Thread Id: 1 (name 'NewThread-2')
            which looks a lot more like assigning a unique Id to a thread.

            Is there something more subtle at play here which I'm not getting? Why would the int returned by uniqueId be thread-local, if uniqueId itself isn't?
            • 3. Re: ThreadLocal and the API doc
              843790
              Actually the 1.7 API doc for ThreadLocal fixes it... my bad, should have checked that first. (http://java.sun.com/javase/7/docs/api/)
              • 4. Re: ThreadLocal and the API doc
                782681
                there is a known bug ([6475885|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6475885]) - dicsussed in an older thread ["Error in ThreadLocal's JavaDoc?"|http://forums.sun.com/thread.jspa?threadID=5386319]