5 Replies Latest reply: Jul 15, 2009 7:35 PM by EJP RSS

    ThreadLocal.get returns a single instance

    799396
      Hi I'm using ThreadLocal for my SimpleDateFormat. Here is the code:
      public class ThreadLocalDateFormatterTester implements Runnable {
              private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
                protected SimpleDateFormat initialValue() {
                     return new SimpleDateFormat("yyyy-MM-dd-HH:mm.ss");
                }
      
            };
      
              private void callDateParser() {
                DateFormat dateFormat = threadLocal.get();
                StringBuilder builder = new StringBuilder();
                builder.append("\n\nFIRST THREAD LOCAL");
                      //i believe that dateFormat for different Threads should be different
                builder.append("\nCLASS:\t" + dateFormat);
                builder.append("\nDATE:\t" + dateFormat.format(new Date(System.currentTimeMillis())));
                builder.append("\nTHREAD:\t" + Thread.currentThread());
                builder.append("\nTLOC:\t" + threadLocal);
                System.out.println(builder);
              }
      
              public static void main(String[] args) {
                     ThreadLocalDateFormatterTester tester = new ThreadLocalDateFormatterTester();
                new Thread(tester).start();
                
                ThreadLocalDateFormatterTester tester2 = new ThreadLocalDateFormatterTester();
                new Thread(tester2).start();
              }
      }
      This is the output:
      FIRST THREAD LOCAL
      CLASS:     java.text.SimpleDateFormat@d6f067a1
      DATE:     2009-07-15-15:25.47
      THREAD:     Thread[Thread-0,5,main]
      TLOC:     threadlocal.ThreadLocalDateFormatterTester$1@c9ba38
      
      
      FIRST THREAD LOCAL
      CLASS:     java.text.SimpleDateFormat@d6f067a1
      DATE:     2009-07-15-15:25.47
      THREAD:     Thread[Thread-1,5,main]
      TLOC:     threadlocal.ThreadLocalDateFormatterTester$1@c9ba38
      Now, I.m just wondering why did the 2 threads use the same SimpleDateFormat? It is correct that they use the single threadLocal because it is static but I think they should use different SimpleDateFormats because they are in different Threads. How did this happen?

      Thanks!
        • 1. Re: ThreadLocal.get returns a single instance
          791266
          They aren't using the same formatter. Add this line to your printouts:

          builder.append("\nInstance id:\t" + System.identityHashCode(dateFormat));

          Do also note that you aren't printing out the class on the line that says CLASS.
          • 2. Re: ThreadLocal.get returns a single instance
            791266
            The reason to why you see what you see is that toString in Object does this:
               public String toString() {
                 return getClass().getName() + "@" + Integer.toHexString(hashCode());
                }
            And hashCode() in SimpleDateFormat does this:
                public int hashCode()
                {
                    return pattern.hashCode();
                    // just enough fields for a reasonable distribution
                }
            • 3. Re: ThreadLocal.get returns a single instance
              796440
              The only way to be sure that two references point to the same object is with a == b. However, System.identityHashCode not being equal is enough to prove they're not the same object.
              • 4. Re: ThreadLocal.get returns a single instance
                799396
                Thank kajbj. Different threads use different SimpleDateFormat. Thanks for the
                System.identityHashCode(dateFormat)
                • 5. Re: ThreadLocal.get returns a single instance
                  EJP
                  private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
                  So threadLocal is static.
                            builder.append("\nTLOC:\t" + threadLocal);
                  So this will always print out the same thing.
                  Now, I'm just wondering why did the 2 threads use the same SimpleDateFormat?
                  They didn't, and you have no evidence that they did.
                  It is correct that they use the single threadLocal because it is static but I think they should use different SimpleDateFormats because they are in different Threads. How did this happen?
                  It didn't. You didn't print anything that supported your belief.