<img alt="" src="https://secure.leadforensics.com/150446.png " style="display:none;">

When to use ThreadLocal?

Madhura Oak Jun 19, 2012

Context Object Java Tomcat JBoss Multithreading ThreadLocal InheritableThreadLocal memory leak Technology

JDK 1.2 introduced ThreadLocal class to maintain the thread’s local state. A thread may need to share some state with the classes in which it runs and a thread may have its own local state. To maintain such state in the thread-scope, ThreadLocal can be used instead of declaring the state in the Thread class and using synchronization to share it.

Many values such as the transaction id, user details, authentication and authorization details, database connection may need to be maintained and shared within a single thread. They can be stored in the ThreadLocal. The Java EE application servers use ThreadLocal to maintain the transaction context in EJBs.

The ThreadLocal has a subclass InheritableThreadLocal which allows the child threads to inherit its values.

ThreadLocal should not be used for storing global variables or to share method arguments.

If the ThreadLocal creates new instances for values, they become implicitly thread-safe since they are not shared by more than one thread. Synchronization needs to be taken care while using shared instances such as pooled database connections.

The initialValue() method is used to set the initial value of ThreadLocal. The set() and get() methods are used to set and get the values respectively. The remove() method introduced in Java 5 removes the ThreadLocal instance from the thread. Once a ThreadLocal is removed it can be garbage collected. Always ensure to explicitly remove the ThreadLocal instances or set their value to null to avoid memory leak.

A map of ThreadLocal weak reference as key and its value as value is maintained for each thread. The reference to a ThreadLocal is held as long as the thread is alive. As soon as the thread is dead, its instances of ThreadLocal are eligible for garbage collection. The memory allocated to these ThreadLocal instances is guarenteed to be reclaimed when the memory runs out of space.

While using ThreadLocal you may need to define multiple typed ThreadLocal<T> classes if you wish to store typed information or you can simply use a single ThreadLocal<Object> class to encapsulate state of various types. You can create multiple instances of ThreadLocal to store multiple state or you can store multiple state in a single POJO class and add it as a value in ThreadLocal (saving a Context Object within a ThreadLocal).

Unfortunately, multiple issues of memory leaks have been reported in Tomcat and JBoss 1.2 with the use of ThreadLocal in the Java EE applications. Application servers usually use pooled threads for better performance instead of creating a new thread for serving client requests. Due to the pooling of threads, its ThreadLocal instances were not garbage collected leading to memory leak. There was also a memory leak when a ThreadLocal instance used another ThreadLocal instance as value.

With memory leaks, the application servers failed to reclaim the memory allocated to ThreadLocal instances or they were not garbage collected which resulted either in OutOfMemoryError or slowness of the application. The issues occurred when the application was redeployed multiple times in the application server. The heap dump had to be obtained and analyzed to identify the issues.

Most of the memory leaks are now identified by Tomcat and fixed in version 7.0.6 and later.

When to use ThreadLocal?

A single thread is used when a request is dispatched through multiple web components. The state variables local to a thread can be maintained in request scope. To share state in request scope in a web application, the ServletRequest attributes can be used.

Context Object, a Core J2EE design pattern, can be used to encapsulate the state and share it in in request scope in a web application. Sharing state by using request attributes should be preferred instead of using ThreadLocal. Unlike ThreadLocal, there is no need to explicitly remove the state from request scope when its use is over while using these attributes to avoid the possibility of memory leaks.

Request Context POJO strategy is commonly used to share state which is local to a thread for e.g. ActionForm in Struts. Using Request Context POJO strategy is a more elegant approach to maintain thread’s local state in request scope instead of using ThreadLocal.

The Struts Framework provides ActionForm (Request Context POJO strategy) and DynaActionForm (Hybrid Request Context POJO strategy) to share the state by a thread in request scope.

ThreadLocal can be used to share state in class and application scope but such use of ThreadLocal to share global state is discouraged.

Using ThreadLocal in a web component should be avoided. However, the third-party APIs used in a web application may use ThreadLocal.

ThreadLocal should only be used in applications which do not provide any way to maintain local variables for a thread.

Similar Blog

e-Zest is a leading digital innovation partner for enterprises and technology companies that utilizes emerging technologies for creating engaging customers experiences. Being a customer-focused and technology-driven company, it always helps clients in crafting holistic business value for their software development efforts. It offers software development and consulting services for cloud computing, enterprise mobility, big data and analytics, user experience and digital commerce.