Wednesday, November 7, 2012

ThreadLocal in Java

One of the most critical aspects of a concurrent application is shared data. This has special importance in those objects that extend the Thread class or implement the Runnable interface. If you create an object of a class that implements the Runnable interface and then start various Thread objects using the same Runnable object, all the threads share the same attributes. This means that, if you change an attribute in a thread, all the threads will be affected by this change.
Sometimes, you will be interested in having an attribute that won't be shared between all the threads that run the same object. The Java Concurrency API provides a clean mechanism called thread-local variables with a very good performance.

We use ThreadLocal when you have some object that is not thread-safe, but you want to avoid synchronizing access to that object. Instead, we give each thread its own instance of the object. There are many Different ways of implementing thread safe operation like :
What is Thread Safe
Thread is a single line of process when there is multi-threading applications, we means there are multiple process that run through the same line of code. In such situation, there is a chance that one thread will modify/accessing the data of another thread. When data cannot be shared like this, then we make the operation thread safe.

Core concept of ThreadLocal is that every thread that access the ThreadLocal variable through get and set methods of ThreadLocal has own, independently initialized copy of the variable. This class provide the thread-local variables.
How does this thread-local variable differ from their counterpart normal variable is that in each thread that access thread-local variable via its methods has its own,independently initialized copy of the variable. ThreadLocal instance are privately static fields in classes that wish to associate state with a thread.It can be accessed from anywhere inside a thread.

ThreadLocal is a thread-scope like scopes in JSP(session scope).You can set any object in ThreadLocal and this object will be global and local to specific thread which is accessing the object.

  • Global means they can be accessed from anywhere inside the thread if a thread call a methods from different classes, then all the methods can see the ThreadLocal variable set by others methods because they are executing in a same thread. 
  • Local means that each thread will have its own thread local variable.One thread can not access/modify other thread local variable.

Getting ready..
In order to understand the concept, we will develop a program that has the problem exposed as discussed above and another program that solves this problem using the thread-local variables mechanism.
Output:
Starting thread 8 : Sat Aug 09 13:39:32 IST 2014
Starting thread 9 : Sat Aug 09 13:39:34 IST 2014
Starting thread 10 : Sat Aug 09 13:39:36 IST 2014
Thread finished 8 : Sat Aug 09 13:39:36 IST 2014
Starting thread 11 : Sat Aug 09 13:39:38 IST 2014
Thread finished 9 : Sat Aug 09 13:39:38 IST 2014
Starting thread 12 : Sat Aug 09 13:39:40 IST 2014
Thread finished 10 : Sat Aug 09 13:39:40 IST 2014
Thread finished 11 : Sat Aug 09 13:39:40 IST 2014
Thread finished 12 : Sat Aug 09 13:39:40 IST 2014

In the above output, you can see the results of this program's execution. Each Thread has a different start time but, when they finish, all have the same value in its startDate attribute.

Now,we are going to use the thread-local variables mechanism to solve this problem.
Output:
Starting thread 8 : Sat Aug 09 13:49:25 IST 2014
Starting thread 9 : Sat Aug 09 13:49:27 IST 2014
Starting thread 10 : Sat Aug 09 13:49:29 IST 2014
Thread finished 8 : Sat Aug 09 13:49:25 IST 2014
Starting thread 11 : Sat Aug 09 13:49:31 IST 2014
Thread finished 9 : Sat Aug 09 13:49:27 IST 2014
Starting thread 12 : Sat Aug 09 13:49:33 IST 2014
Thread finished 10 : Sat Aug 09 13:49:29 IST 2014
Thread finished 11 : Sat Aug 09 13:49:31 IST 2014
Thread finished 12 : Sat Aug 09 13:49:33 IST 2014

Now, the Thread objects have their own value of the startDate attribute.

Thread-local variables store a value of an attribute for each Thread that uses one of these variables. You can read the value using the get() method and change the value using the set() method. The first time you access the value of a thread-local variable, if it has no value for the Thread object that it is calling, the thread-local variable calls the initialValue() method to assign a value for that Thread and returns the initial value.

When to use Thread Local
Today Whatever the application be like banking, telecommunications etc we need some sort of transaction id, user id for every request. Consider an example, you have servlet that call some business methods. You have requirement to generate a unique ID for every transaction that this servlet will process and then you need to pass this transaction ID to some other business methods, for instance, logging purpose.
One solution will be passing this transaction ID in the parameters to all the business methods.  Suppose if you have more than 10+ methods ,you will pass the transaction ID in the parameters to each methods that will redundant and unnecessary

To solve this, use can use ThreadLocal. First you can generate the transaction ID may be in servlet or filter and sets in a thread local. After this whatever business method this servlet call, can access the transaction ID from ThreadLocal. Servlet can be processing more than one request. Since each request is processed in a separate thread, the transaction ID will be unique to each thread(local) and will be accessible from all over the thread execution.

Example: 
TransactionContext.java : hold the transaction ID

MyThreadLocal.java : container to hold TransactionContext  object.

BuisnessClass.java : contain the business method

BuisnessClass1.java : contain the business method

ThreadLocalExample.java : main class that first generate the ID, then set by calling the set() method.


Output
Thread-0 JavaLatte-91996810
Thread-1 JavaLatte-1049236749
Thread-0 JavaLatte-91996810
Thread-1 JavaLatte-1049236749

If you look at the output, once we set the transaction ID for one thread, then it can be accessible from any business method that it will call.

There's more...
The thread-local class also provides the remove() method that deletes the value stored in the thread-local variable for the thread that it's calling.

The Java Concurrency API includes the InheritableThreadLocal class that provides inheritance of values for threads created from a thread. If a thread A has a value in a thread-local variable and it creates another thread B, the thread B will have the same value as the thread A in the thread-local variable. You can override the childValue() method that is called to initialize the value of the child thread in the thread-local variable. It receives the value of the parent thread in the thread-local variable as a parameter.



If you know anyone who has started learning Java, why not help them out! Just share this post with them. Thanks for studying today!...

1 comment:

  1. I am technology Enthusiast. Your blog is really awesome, attractive and impressive. I like the way you think. it is very useful for Java SE & Java EE Learners. Your article adds best knowledge to our Java Online Training in India. or learn thru Java Online Training in India Students. or learn thru JavaScript Online Training in India. Appreciating the persistence you put into your blog and detailed information you provide. Kindly keep blogging.

    ReplyDelete