My name is Veera. I'm a full stack web developer. I have founded http://www.timethetask.com and currently working on my next product. Veera is a DZone MVB and is not an employee of DZone and has posted 33 posts at DZone. You can read more from them at their website. View Full User Profile

Java Thread Local – How to Use and Code Sample

11.23.2010
| 163721 views |
  • submit to reddit

Thread Local is an interesting and useful concept, yet most of the Java developers are not aware of how to use that. In this post, I’ll explain what is Thread Local and when to use it, with an example code.

Since it’ll be little tough to understand this concept at first, I’ll keep the explanation as simple as possible (corollary: you shouldn’t use this code as it is in a production environment. Grasp the concept and improve upon it!)

Let’s begin.

What is Thread Local?

Thread Local can be considered as a scope of access, like a request scope or session scope. It’s a thread scope. You can set any object in Thread Local and this object will be global and local to the specific thread which is accessing this object. Global and local!!? Let me explain:

  • Values stored in Thread Local are global to the thread, meaning that they can be accessed from anywhere inside that thread. If a thread calls methods from several classes, then all the methods can see the Thread Local variable set by other methods (because they are executing in same thread). The value need not be passed explicitly. It’s like how you use global variables.
  • Values stored in Thread Local are local to the thread, meaning that each thread will have it’s own Thread Local variable. One thread can not access/modify other thread’s Thread Local variables.

Well, that’s the concept of Thread Local. I hope you understood it (if not, please leave a comment).

When to use Thread Local?

We saw what is thread local in the above section. Now let’s talk about the use cases. i.e. when you’ll be needing something like Thread Local.

I can point out one use case where I used thread local. Consider you have a Servlet which calls some business methods. You have a requirement to generate a unique transaction id for each and every request this servlet process and you need to pass this transaction id to the business methods, for logging purpose. One solution would 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, you can use Thread Local. You can generate a transaction id (either in servlet or better in a filter) and set it in the Thread Local. After this, what ever the business method, that this servlet calls, can access the transaction id from the thread local.

This servlet might be servicing more that one request at a time. Since each request is processed in separate thread, the transaction id will be unique to each thread (local) and will be accessible from all over the thread’s execution (global).

Got it!?

How to use Thread Local?

Java provides an ThreadLocal object using which you can set/get thread scoped variables. Below is a code example demonstrating what I’d explained above.

Lets first have the Context.java file which will hold the transactionId field.

package com.veerasundar;

public class Context {

private String transactionId = null;

/* getters and setters here */

}

Now create the MyThreadLocal.java file which will act as a container to hold our context object.

package com.veerasundar;

/**
* this class acts as a container to our thread local variables.
* @author vsundar
*
*/
public class MyThreadLocal {

public static final ThreadLocal userThreadLocal = new ThreadLocal();

public static void set(Context user) {
userThreadLocal.set(user);
}

public static void unset() {
userThreadLocal.remove();
}

public static Context get() {
return userThreadLocal.get();
}
}

In the above code, you are creating a ThreadLocal object as a static field which can be used by rest of the code to set/get thread local variables.

Let’s create our main class file which will generate and set the transaction ID in thread local and then call the business method.

package com.veerasundar;

public class ThreadLocalDemo extends Thread {

public static void main(String args[]) {

Thread threadOne = new ThreadLocalDemo();
threadOne.start();

Thread threadTwo = new ThreadLocalDemo();
threadTwo.start();
}

@Override
public void run() {
// sample code to simulate transaction id
Context context = new Context();
context.setTransactionId(getName());

// set the context object in thread local to access it somewhere else
MyThreadLocal.set(context);

/* note that we are not explicitly passing the transaction id */
new BusinessService().businessMethod();
MyThreadLocal.unset();

}
}

Finally, here’s the code for the BusinessService.java which will read from thread local and use the value.

package com.veerasundar;

public class BusinessService {

public void businessMethod() {
// get the context from thread local
Context context = MyThreadLocal.get();
System.out.println(context.getTransactionId());
}
}

When you run the ThreadLocalDemo file, you’ll get the below output:

Thread-0
Thread-1

As you might see, even though we are not explicitly passing the transaction id, the value can be accessed from the business method and printed on the console. Adding to it, the transaction ID differs for each thread (0 and 1).

Well, that’s it. I hope I’d explained it in a simple possible way. Please let me know what do you think about this article in comments. Do leave a comment if you want to add anything to this topic.

From http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/

Published at DZone with permission of Veera Sundar, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Tony Siciliani replied on Tue, 2010/11/23 - 4:59am

Why is userThreadLocal declared public? AFAIK, ThreadLocal instances are typically private static fields.

 Also, ThreadLocal is a generic type, it is ThreadLocal<T>.

An important benefit of ThreadLocal worth mentioning (from 1.4 JVMs forward), is as an alternative to synchronization, to improve scalability in transaction-intensive environments. Classes encapsulated in ThreadLocal are automatically thread-safe in a pretty simple way, since  it's clear that anything stored in ThreadLocal is not shared between threads.

 

Christian Schli... replied on Tue, 2010/11/23 - 7:26am

Nice post! In your sample code however, MyThreadLocal isn't required. You could simply use a private static ThreadLocal tl = new ThreadLocal<Context>(); definition in ThreadLocalDemo. If you need an initial value for the thread local, then you should extend ThreadLocal and override the initialValue() method.

matt inger replied on Tue, 2010/11/23 - 11:03am

Don't forget about InheritableThreadLocal which is a subclass which allows child threads to inherit their value from the parent thread:

       final ThreadLocal<String> inheritable = new InheritableThreadLocal<String>();

        inheritable.set("foo");

        Thread t = new Thread() {
          public void run() {
             System.out.println(Thread.currentThread().getName() + " " + inheritable.get());
          }
        };

        t.start();
        t.join();
        
        System.out.println(Thread.currentThread().getName() + " " + inheritable.get());

This produces output like this:

Thread-0 foo
main foo

If you had used a normal ThreadLocal, and not InheritableThreadLocal, it would have produced:

Thread-0 null
main foo

matt inger replied on Tue, 2010/11/23 - 11:28am in response to: Tony Siciliani

This is not 100% true on the "not shared between threads" point. There's no guarantee that your ThreadLocal wasn't instantiated as an InheritableThreadLocal, in which case, you could be sharing a value across threads, so there has to be knowledge of whether or not you're using the inheritable version.

Andreas Pokrzywinski replied on Fri, 2010/11/26 - 2:47pm

Be aware of thread pools in application servers. The ThreadLocale must always be reset. Do the following on every system boundary (fe WebService)

try {
      ... 
} finally {
 MyThreadLocal.unset();
 }

 

Willie Chieukam replied on Sat, 2011/02/05 - 2:33am

Really nice article!

Sachin Hadke replied on Thu, 2011/02/10 - 3:48am

Very nice artical for novice user. Thanks Veera for posting it.

I agree to Tony, that the userThreadLocal should be decleard as private as per SDK documentation. But the main topic was to explain ThreadLocal.

Christian was also true, however to set the initialValue one has to define a class that extend ThreadLocal, or create an Anonymous class.

About Matt's commnet on InheritableThreadLocal. The InheritableThreadLocal is mainly use when child thread may or may not set the ThreadLocal value but still want to be aware of ThreadLocal created by daemon or parent thread.

 

Chaithanya Kanumolu replied on Tue, 2011/07/26 - 11:14pm

Hi, That's a nice short article, I just want to know, can ThreadLocal store more than one bean? I mean similar to properties file. Thanks in advance, Chaithanya K.

Dimit Chadha replied on Tue, 2013/03/19 - 4:40am

Excellent Example. 

ThreadLocal in Java is another way to achieve thread-safety apart from writing immutable classes. In multi-threaded applications there is a cost of synchronization or locking which greatly affects scalability of application, but there is no choice other than synchronize if you are sharing objects between multiple threads.

One Query : Can we use Thread local for storing http session variables in-case we have session wrappers in application.


Keeping writing

www.javapathshala.com

Shafi Shaik replied on Wed, 2014/09/17 - 9:09pm

 Thanks for Information. Please suggest me books regarding Mulitthreading in java Thank you.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.