Thursday, September 14, 2023

ThreadLocal in Java - Example Program and Tutorial

ThreadLocal in Java is another way to achieve thread-safety apart from writing immutable classes. If you have been writing multi-threaded or concurrent code in Java then you must be familiar with the cost of synchronization or locking which can greatly affect the Scalability of application, but there is no choice other than synchronizing if you are sharing objects between multiple threads. ThreadLocal in Java is a different way to achieve thread-safety, it doesn't address synchronization requirement, instead, it eliminates sharing by providing an explicit copy of Object to each thread. Since Object is no more shared there is no requirement of Synchronization which can improve scalability and performance of the application.

In this Java ThreadLocal tutorial, we will see important points about ThreadLocal in Java, when to use ThreadLocal in Java, and a simple example of ThreadLocal in Java program.

And, if you are serious about mastering Java multi-threading and concurrency then I also suggest you take a look at the Java Multithreading, Concurrency, and Performance Optimization course by Michael Pogrebinsy on Udemy. It's an advanced course to become an expert in Multithreading, concurrency, and Parallel programming in Java with a strong emphasis on high performance


When to use ThreadLocal in Java

Many Java Programmers question where to use ThreadLocal in Java and some even argue the benefit of the ThreadLocal variable, but ThreadLocal has many genuine use cases and that's why it's added to the standard Java Platform Library. I agree though until you are not in concurrent programming, you will rarely use ThreadLocal. below are some well know usage of ThreadLocal class in Java:



1) ThreadLocal is fantastic to implement Per Thread Singleton classes or per thread context information like transaction id.

2) You can wrap any non Thread Safe object in ThreadLocal and suddenly its uses become Thread-safe, as it's only being used by Thread Safe. One of the classic examples of ThreadLocal is sharing SimpleDateForamt. Since SimpleDateFormat is not thread-safe, having a global formatter may not work but having per Thread formatter will certainly work.

3) ThreadLocal provides another way to extend Thread. If you want to preserve or carry information from one method call to another you can carry it by using ThreadLocal. This can provide immense flexibility as you don't need to modify any method.

On a basic level, ThreadLocal provides Thread Confinement which is an extension of the local variable. while the local variable is only accessible on the block they are declared, ThreadLocal is visible only in Single Thread. 

No two Thread can see each other's ThreadLocal variable. A real-Life example of ThreadLocal is in J2EE application servers which uses java ThreadLocal variable to keep track of transaction and security Context. It makes a lot of sense to share heavy objects like Database Connection as ThreadLocal in order to avoid excessive creation and cost of locking in case of sharing global instance.

Java ThreadLocal Example – Code

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 * @author
 */

public class ThreadLocalTest {

    public static void main(String args[]) throws IOException {
        Thread t1 = new Thread(new Task());  
        Thread t2 = new Thread( new Task());
     
        t1.start();
        t2.start();      
     
    }
   
    /*
     * Thread safe format method because every thread will use its own DateFormat
     */

    public static String threadSafeFormat(Date date){
        DateFormat formatter = PerThreadFormatter.getDateFormatter();
        return formatter.format(date);
    }
   
}


/*
 * Thread Safe implementation of SimpleDateFormat
 * Each Thread will get its own instance of SimpleDateFormat which will not be shared between other threads. *
 */

class PerThreadFormatter {

    private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {

        /*
         * initialValue() is called
         */

        @Override
        protected SimpleDateFormat initialValue() {
            System.out.println("Creating SimpleDateFormat for Thread : " + Thread.currentThread().getName());
            return new SimpleDateFormat("dd/MM/yyyy");
        }
    };

    /*
     * Every time there is a call for DateFormat, ThreadLocal will return calling
     * Thread's copy of SimpleDateFormat
     */

    public static DateFormat getDateFormatter() {
        return dateFormatHolder.get();
    }
}

class Task implements Runnable{
   
    @Override
    public void run() {
        for(int i=0; i<2; i++){
            System.out.println("Thread: " + Thread.currentThread().getName() + " Formatted Date: " + ThreadLocalTest.threadSafeFormat(new Date()) );
        }      
    }
}

Output:
Creating SimpleDateFormat for Thread: Thread-0
Creating SimpleDateFormat for Thread: Thread-1
Thread: Thread-1 Formatted Date: 30/05/2012
Thread: Thread-1 Formatted Date: 30/05/2012
Thread: Thread-0 Formatted Date: 30/05/2012
Thread: Thread-0 Formatted Date: 30/05/2012

If you look at the output of the above program then you will find that when a different thread calls getFormatter() method of ThreadLocal class than its call its initialValue() method which creates an exclusive instance of SimpleDateFormat for that Thread. 

Since SimpleDateFormat is not shared between thread and essentially local to the thread which creates its own  threadSafFormat() method is completely thread-safe. 

You can further join an advanced course like Concurrency, Multithreading, and Parallel Computing in Java by Holczer Balazes on Udemy to learn advanced concurrency concepts like fork-join pool, map-reduce, and parallel programming. 



ThreadLocal in Java - Example Program and Tutorial


Important points on Java ThreadLocal Class

1. ThreadLocal in Java is introduced on JDK 1.2 but it later generified in JDK 1.4 to introduce type safety on ThreadLocal variable.ThreadLocal Code Example in Java

2. ThreadLocal can be associated with Thread scope, all the code which is executed by Thread has access to ThreadLocal variables but two thread can not see each other's ThreadLocal variable.

3. Each thread holds an exclusive copy of the ThreadLocal variable which becomes eligible to Garbage collection after thread finished or died, normally or due to any Exception, Given those ThreadLocal variable doesn't have any other live references.

4. ThreadLocal variables in Java are generally private static fields in Classes and maintain its state inside Thread.

We saw how ThreadLocal in Java opens another avenue for thread-safety. Though the concept of thread-safety by confining object to Thread is there from JDK 1.0 and many programmers have their own custom ThreadLocal classes, having ThreadLocal in Java API makes it a lot more easy and standard. Think about the ThreadLocal variable while designing concurrency in your application. 

Don't misunderstand that ThreadLocal is an alternative to Synchronization, it all depends upon the design. If the design allows each thread to have their own copy of the object then ThreadLocal is there to use.

Further Learning
Multithreading and Parallel Computing in Java
Java Concurrency in Practice - The Book
Applying Concurrency and Multi-threading to Common Java Patterns
Java Concurrency in Practice Course by Heinz Kabutz


Other Java tutorials on Threading you may find useful

Thanks for reading this article so far. If you find this Information useful then please comment and share this article with your friends and colleagues. It makes a lot of difference. If you have any doubt, questions, or feedback, please ask and we would be happy to explain. 

And lastly, Let me know in comments if you have used ThreadLocal class in Java? or faced any issue related to ThreadLocal in Java

12 comments :

Anonymous said...

Using ThreadLocal inside web application is very dangerous as it can cause memory leak if you failed to remove ThreadLocal variable when web application stopped. so just beware of that. ThreadLocal's remove() method can be used to remove variable.

Prabhu said...

Out of many ThreadLocal example in Java I have seen yours is most practical, real world and reusable. Can you please suggest how to properly use ThreadLocal in web applications to avoid memory leak as well ?

Anonymous said...

Be careful while using ThreadLocal in J2EE code or web applications especially which you deploy. ThreadLocal can cause ClassLoader memory leak in web application as JVM manages threads in Thread Pool and they live longer than web app itself. If ThreadLocal holds object of your class than it may prevent to clear permgen space during undeployment.

Anonymous said...

ThreadLocal as static? That beats the whole purpose of it isn't it?

Anonymous said...

I have read some blogs and even saw the implementation of ThreadLocal in my project. One point I am confused is that should we call set() on ThreadLocal from Synchronized context? In my project we have

public static synchronized void initThisThread(FeMasterLog log)
{
if (null == log) throw new IllegalArgumentException();
_logs.set(log);
}

where _logs is defined as

private static ThreadLocal _logs = new ThreadLocal();

I believe making the above method synchronized is unnecessary. Is my assumption right?

Srikanth said...

I think so Anonymous
As the example states that each thread has it's own copy of ThreadLocal
_logs.set is called for their respective threads. So, I don't see a reason why it should be in synchronized blocks

Please correct me if I am wrong.

Anonymous said...

LOL sometime its too verbose :) Anyway great article that I was looking for.

"In this Java ThreadLocal tutorial we will see important points about ThreadLocal in Java, when to use ThreadLocal in Java and a simple Example of ThreadLocal in Java program."

Anonymous said...

What is difference between Thread local and local variable in run method. In both case each thread maintain there own var?
Which one we should prefer to use Thread Local or Local Var?

In Case of thread pool does a thread reuse the same thread local var after completion of one task and while picking the next task.

Unknown said...

best use of thread local in hibernate...suppose we want same session object wanted to perform the insertion/deletion/updation..in that case instead of creating 3 specific session object we can put the session object to the ThreadLocal.

javin paul said...

@Md Ajmat, nice one, one of the rare real world usecase of thread local variable.

Anonymous said...

With Virtual Threads in Java 21 its no more actual. If we want to use virtual threads we need use as many ThreadLocal as possible. Java language architects recommend to start avoiding ThreadLocal, they have plans to deprecate it and totally remove.

Anonymous said...

With Virtual Threads in Java 21 its no more actual. If we want to use virtual threads we need use as many ThreadLocal as possible. Java language architects recommend to start avoiding ThreadLocal, they have plans to deprecate it and totally remove.

Post a Comment