HowToDoInJava

  • Java 8
  • Regex
  • Concurrency
  • Best Practices
  • Spring Boot
  • JUnit5
  • Interview Questions
  • Dark Mode

Java ThreadLocal Variables – When and How to Use?

By Lokesh Gupta | Filed Under: Java Concurrency

Today, one of the most critical aspects of a concurrent application is shared data. When you create thread that implements the Runnable interface and then start various Thread objects using the same Runnable object, all the threads share the same attributes that are defined inside the runnable object. This essentially means that if you change any attribute in a thread, all the threads will be affected by this change and will see the modified value by first thread. Sometimes it is desired behavior e.g. multiple threads increasing / decreasing the same counter variable; but sometimes you want to ensure that every thread MUST work on it’s own copy of thread instance and does not affect others data.

When to use ThreadLocal?

For example, consider you are working on a eCommerce application. You have a requirement to generate a unique transaction id for each and every customer request this controller process and you need to pass this transaction id to the business methods in manager/DAO classes for logging purpose. One solution could be passing this transaction id as a parameter to all the business methods. But this is not a good solution as the code is redundant and unnecessary.

To solve that, here you can use ThreadLocal variable. You can generate a transaction id in controller OR any pre-processor interceptor; and set this transaction id in the ThreadLocal. After this, whatever the methods, that this controller calls, they all can access this transaction id from the threadlocal. Also note that application controller will be servicing more that one request at a time and since each request is processed in separate thread at framework level, the transaction id will be unique to each thread and will be accessible from all over the thread’s execution path.

Read More : Share context data with JAX-RS ResteasyProviderFactory (ThreadLocalStack Example)

Inside ThreadLocal Class?

The Java Concurrency API provides a clean mechanism for thread-local variables using ThreadLocal class with a very good performance.

public class ThreadLocal<T> extends Object {...}

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

This class has following methods:

  1. get() : Returns the value in the current thread’s copy of this thread-local variable.
  2. initialValue() : Returns the current thread’s “initial value” for this thread-local variable.
  3. remove() : Removes the current thread’s value for this thread-local variable.
  4. set(T value) : Sets the current thread’s copy of this thread-local variable to the specified value.

How to use ThreadLocal?

Below example uses two thread local variables i.e. threadId and startDate. Both have been defined as “private static” fields as recommended. ‘threadId‘ will be used to identify the thread which is currently running and ‘startDate‘ will be used to get the time when thread started it’s execution. Above information will be printed in console to verify that each thread has maintained it’s own copy of variables.

class DemoTask implements Runnable
{
   // Atomic integer containing the next thread ID to be assigned
   private static final AtomicInteger        nextId   = new AtomicInteger(0);
   
   // Thread local variable containing each thread's ID
   private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>()
                                                         {
                                                            @Override
                                                            protected Integer initialValue()
                                                            {
                                                               return nextId.getAndIncrement();
                                                            }
                                                         };

   // Returns the current thread's unique ID, assigning it if necessary
   public int getThreadId()
   {
      return threadId.get();
   }
   // Returns the current thread's starting timestamp
   private static final ThreadLocal<Date> startDate = new ThreadLocal<Date>()
                                                 {
                                                    protected Date initialValue()
                                                    {
                                                       return new Date();
                                                    }
                                                 };

  

   @Override
   public void run()
   {
      System.out.printf("Starting Thread: %s : %s\n", getThreadId(), startDate.get());
      try
      {
         TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
      } catch (InterruptedException e)
      {
         e.printStackTrace();
      }
      System.out.printf("Thread Finished: %s : %s\n", getThreadId(), startDate.get());
   }
}

Now to verify that variables essentially are able to maintain their state irrespective of multiple initializations for multiple threads, let’s create three instances of this task; start the threads; and then verify the information they print in console.

Starting Thread: 0 : Wed Dec 24 15:04:40 IST 2014
Thread Finished: 0 : Wed Dec 24 15:04:40 IST 2014

Starting Thread: 1 : Wed Dec 24 15:04:42 IST 2014
Thread Finished: 1 : Wed Dec 24 15:04:42 IST 2014

Starting Thread: 2 : Wed Dec 24 15:04:44 IST 2014
Thread Finished: 2 : Wed Dec 24 15:04:44 IST 2014

In above output, sequence of printed statement will vary everytime. I have put them in sequence so that we can clearly identify that thread local values are kept safe for each thread instance; and never intermixed. Try yourself.

Most common use of thread local is when you have some object that is not thread-safe, but you want to avoid synchronizing access to that object using synchronized keyword/block. Instead, give each thread its own instance of the object to work with.
A good alternative to synchronization or threadlocal is to make the variable a local variable. Local variables are always thread safe. The only thing which may prevent you to do this is your application design constraints.
In wabapp server, it may be keep a thread pool, so a ThreadLocal var should be removed before response to the client, since current thread may be reused by next request. Also, if you do not clean up when you’re done, any references it holds to classes loaded as part of a deployed webapp will remain in the permanent heap and will never get garbage collected.

Happy Learning !!

TwitterFacebookLinkedinRedditPocket

About Lokesh Gupta

A family guy with fun loving nature. Love computers, programming and solving everyday problems. Find me on Facebook and Twitter.

6
Leave a Reply

This comment form is under antispam protection
4 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
6 Comment authors
This comment form is under antispam protection
  Subscribe  
newest oldest most voted
Notify of
649239538

The above code is still error . The two ThreadLocal variables are still in runnable and not shared !

Vote Up0Vote Down  Reply
2 months ago
Himansu Nayak

Hi Lokesh,

Going thru “ThreadLocal” i found “InheritableThreadLocal” but never found and good examples on it. Can you please explain on this and if possible can you also enlighten the internal data structure of the ThreadLocal i.e “ThreadLocalMap” and “WeekReference”

Vote Up0Vote Down  Reply
4 years ago
Dilip

InheritabelThreadLocal is used in the situation of Parent Thread-Child Threads resource sharing.

It can be used when Child Thread wishes to utilize the local variables of it’s parent thread.

Imagine a Process which forks no. of Child threads for concurrent processing and every individual child thread needs to mark it’s completion so that Parent Thread can track (e.g. Thread Processing Completion Count)

Vote Up0Vote Down  Reply
2 years ago
Binh Thanh Nguyen

Thanks, nice post

Vote Up0Vote Down  Reply
4 years ago
SJaziri

Hi Lokesh,

Thank you for your interesting post.

you said in the introduction “all the threads share the same attributes that have been defined inside run() method”.

I think you wanted to say : all threads share the same attributes of the runnable object, because attributes defined inside run method are not sharable, they live in the stack and every thread has its own stack.

Vote Up0Vote Down  Reply
4 years ago
Lokesh Gupta

You are right. It is a mistake indeed. Corrected it. Thanks for pointing out.

Vote Up0Vote Down  Reply
4 years ago

Search Tutorials

Java Concurrency Tutorial

  • Java Concurrency – Introduction
  • Concurrency Evolution
  • Thread Safety
  • Concurrency vs. Parallelism
  • Compare and Swap [CAS]
  • synchronized keyword
  • Object vs. Class Level Locking
  • Runnable vs. Thread
  • wait(), notify() and notifyAll()
  • Yield() vs. Join()
  • Sleep() vs. Wait()
  • Lock vs. Monitor
  • Callable + Future
  • UncaughtExceptionHandler
  • Throttling Task Submission
  • Executor Best Practices
  • Inter-thread Communication
  • Write and Resolve Deadlock

Java Concurrency Utilities

  • AtomicInteger
  • Lock
  • ThreadFactory
  • ThreadLocal
  • ExecutorService
  • ThreadPoolExecutor
  • FixedSizeThreadPoolExecutor
  • ScheduledThreadPoolExecutor
  • Semaphore
  • Binary Semaphore
  • BlockingQueue
  • DelayQueue
  • ConcurrentLinkedDeque
  • CountDownLatch
  • ForkJoinPool

Popular Tutorials

  • Java 8 Tutorial
  • Core Java Tutorial
  • Collections in Java
  • Java Concurrency
  • Spring Boot Tutorial
  • Spring AOP Tutorial
  • Spring MVC Tutorial
  • Spring Security Tutorial
  • Hibernate Tutorial
  • Python Tutorial
  • Jersey Tutorial
  • Maven Tutorial
  • Log4j Tutorial
  • Regex Tutorial

Meta Links

  • Advertise
  • Contact Us
  • Privacy policy
  • About Me

Recommended Reading

  • 10 Life Lessons
  • Secure Hash Algorithms
  • How Web Servers work?
  • How Java I/O Works Internally?
  • Best Way to Learn Java
  • Java Best Practices Guide
  • Microservices Tutorial
  • REST API Tutorial
  • How to Start New Blog

Copyright © 2016 · HowToDoInjava.com · All Rights Reserved. | Sitemap

wpDiscuz