Tutorial

Java ThreadLocal Example

Published on August 3, 2022
author

Pankaj

Java ThreadLocal Example

Java ThreadLocal is used to create thread local variables. We know that all threads of an Object share it’s variables, so the variable is not thread safe. We can use synchronization for thread safety but if we want to avoid synchronization, we can use ThreadLocal variables.

Java ThreadLocal

ThreadLocal, Java ThreadLocal Every thread has it’s own ThreadLocal variable and they can use it’s get() and set() methods to get the default value or change it’s value local to Thread. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.

Java ThreadLocal Example

Here is a small example showing use of ThreadLocal in java program and proving that every thread has it’s own copy of ThreadLocal variable. ThreadLocalExample.java

package com.journaldev.threads;

import java.text.SimpleDateFormat;
import java.util.Random;

public class ThreadLocalExample implements Runnable{

    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };
    
    public static void main(String[] args) throws InterruptedException {
        ThreadLocalExample obj = new ThreadLocalExample();
        for(int i=0 ; i<10; i++){
            Thread t = new Thread(obj, ""+i);
            Thread.sleep(new Random().nextInt(1000));
            t.start();
        }
    }

    @Override
    public void run() {
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //formatter pattern is changed here by thread, but it won't reflect to other threads
        formatter.set(new SimpleDateFormat());
        
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

Output of the above java ThreadLocal example program is:

Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = M/d/yy h:mm a
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = M/d/yy h:mm a
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 4 formatter = M/d/yy h:mm a
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = M/d/yy h:mm a
Thread Name= 3 formatter = M/d/yy h:mm a
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = M/d/yy h:mm a
Thread Name= 6 formatter = M/d/yy h:mm a
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = M/d/yy h:mm a
Thread Name= 7 formatter = M/d/yy h:mm a
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 9 formatter = M/d/yy h:mm a

As you can see from the output that Thread-0 has changed the value of formatter but still thread-2 default formatter is same as the initialized value. You can see the same pattern for other threads too. Update: ThreadLocal class is extend in Java 8 with a new method withInitial() that takes Supplier functional interface as argument. So we can use lambda expressions to easily create the ThreadLocal instance. For example, above formatter ThreadLocal variable can be defined in one line as below:

private static final ThreadLocal<SimpleDateFormat> formatter = 
	ThreadLocal.<SimpleDateFormat>withInitial
	(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});

If you are new to Java 8 features, please check out Java 8 Features and Java 8 Functional Interfaces. That’s all for ThreadLocal in java programming. Reference: API Doc

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
January 16, 2014

Very nice post. Helped me understand. Thanks.

- Shashank

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    February 22, 2014

    Hi Pankaj, I want to tell you, I follow your posts, I study them. But this post example is not good one. Can you come up with some better example to explain about ThreadLocal class. Thanks in advance!

    - Pankaj Chopra

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      May 5, 2014

      hi, formatter is final, how could change its value via set() method?

      - jeffrey

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        August 20, 2015

        One interesting point about ThreadLocal variable is the global access. Any thread local variable is global to the thread. It can be accessed anywhere from the thread. If, from a thread several methods residing in different classes are called, thread local variable will be visible to all those methods. There is no need to pass the thread local variable as a parameter. At the same time any thread local variable is local to a thread. If there are 10 threads spawned all the 10 threads will have their own thread local variable. One thread can not access/modify other thread’s Thread Local variables.

        - infoj

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          March 22, 2016

          Hi sir, can u give some instances where this could be practically used.I mean wait and notify could be used for Consumer-Producer problems,similarly,where is this concept generally used.

          - Sriharsha

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            June 10, 2016

            Very good article. Below are my comments : This is not required and not in use. protected SimpleDateFormat initialValue() { return new SimpleDateFormat(“yyyyMMdd HHmm”); } Instead this is required : formatter.set(new SimpleDateFormat(“yyyyMMdd HHmm”));

            - yogi g

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              September 13, 2016

              I got the point that ThreadLocal maiitains a private kind of value respective to the threads. But in other sites too,it is given that it could be used as an alternative to synchronization,to improve performance. I just wonder,since we creating a new value(object instance) in its initial value,obviously,all the changes made to that object by that thread will be exclusive to that object only.So maintaining “thread safety”.I could get this even with Out ThreadLocal variable or Synchronized block,if i am creating a new Instance for every thread. Could some one please explain, what is special in this ThreadLocal for making its things private,isn’t it obvious? Couldn’t i get same thing,by making separate objects,without ThreadLocal and achieve this thread safety?

              - Sriharsha

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                October 16, 2016

                I’m try to understand how to use the ThreadLocal class. I understand that there is a cleanup phase but this article doesn’t mention anything about it !

                - Muhammad Gelbana

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  July 12, 2017

                  The lambda expression part at the end, why do you need the “” in front of “withInitial”? I can just call ThreadLocal.withInitial(…), right? Thanks for the great articles!

                  - dz

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    July 16, 2017

                    What I do not see is where ThreadLocalExample that implements Runnable starts … Thank you

                    - Andrey

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Become a contributor for community

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      DigitalOcean Documentation

                      Full documentation for every DigitalOcean product.

                      Resources for startups and SMBs

                      The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                      Get our newsletter

                      Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                      New accounts only. By submitting your email you agree to our Privacy Policy

                      The developer cloud

                      Scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Get started for free

                      Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                      *This promotional offer applies to new accounts only.