Saturday 25 August 2012

Thread Locals in Java

Thread Locals

Thread local  is a scope just as we have static scoped variables which belong to a class or instance scoped variables which belong to an Object. Thread local variables belong to a thread. Each thread would have its own thread local variable. So, threads can't modify each other's thread local variables. Thread variables are a sort of global variables which are restricted to a thread.

When do we use Thread Local variables ?

By default, data is shared between threads. You can refer to my previous post to get an idea about what is shared among threads. You can use Thread Local variables when you want each thread to have its own copy of something. One very important use cases of thread locals is when we have an object that is not thread safe, but we want to avoid synchronizing access to that object. It would be more clear from an example.

Suppose I have a requirement to use use Java Calendar object in my code. Since Java Calendar is not thread safe, we can either have Calendar object as an instance variable or have it as a class variable and provide synchronization to access it. The first method can't be used in most of the production codes because Calendar object creation is an expensive operation. And still if we have 2 threads of the same process accessing the variable, we need synchronization. The second method looks good since we would have only one object of Calendar class, but we would have to take care of synchronization. 

If we don't want to bother about synchronization, we can go for thread local variables in which case, each thread would be given its own local copy of the thread local variable. Another alternative to thread locals or synchronization is to make the variable a local variable. Local variables are always thread safe. But in our case, since Calendar object creation is an expensive operation, it is not recommended to use local variable for Calendar. Since each time the method is called, a Calendar object would be created which is an expensive operation, it would slow down the.

Another very important use case of Thread Local variables is when we want to associate state with a thread. Many frameworks use ThreadLocals to maintain some context related to the current thread. Web applications might store information about the current request and current session in thread local variables so that the application has easy access to them without passing them as parameters every time. Let me explain this with a scenario.

Lets say, we have a Servlet which calls  some methods. You have a requirement to generate a unique transaction ID for each request you receive and pass this transaction ID to the business methods for processing. One way is to generate a unique transaction ID each time the servlet receive a request and pass this trasaction ID to the methods which require it. But this doesn't look good, since passing of transaction ID to all methods which require it is redundant and unnecessary. Instead, we can use thread local variable to store the transaction ID. Every method which requires transaction ID can access it through the thread local variable. The servlet might be receiving many requests, but each request is processed in a separate thread. So, each transaction ID would be local to a thread and would be accessible all through the thread's execution which is what I mean when I say that Thread Local variables are global.

Usage of Thread Local variables in Java

Java provide a class named ThreadLocal by which you can set and get Thread Local variables.
Typically Thread Local variables are static fields in classes. The code below shows you how to create a Thread Local variable.

Problems with Thread Locals

Thread Locals also comes up with many problems and you have to be careful while using thread locals. Thread Locals can lead to classloading leaks. Thread Locals are very dangerous when it comes to long running applications and garbage collection. Let me explain this point a little bit.

If you use thread locals to store some object instance, there is a high risk that the object stored in thread local is never collected by garbage collector when your application runs inside WebLogic Server. This is because WebLogic server maintains a pool of working threads even when the class that created it is garbage collected. So, if you do not clean up when you are done, any references that it holds as part of the webapp deployment will remain in the heap and would never be garbage collected. This problem can be solved through the proper use of Weak References with Thread Locals. 

No comments:

Post a Comment