About Java ThreadLocal

Source: Internet
Author: User

Transferred from: http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/

What is ThreadLocal? A Simple Example

as its name suggests, a single instance of the ThreadLocal can store different values for each thread independently. Therefore, the value stored in a ThreadLocal instance are specific (local) to the current running Thread, any other code lo GIC running on the same thread would see the same value and not the values set on the same instance by other threads. (There is exceptions, like Inhertiablethreadlocal, which inherits parent thread's values by default.)

Let's consider this example:

We have a TransactionManager class this provide static methods to:

    • Start a transaction with a generated ID

    • Store that ID as a static field and provide a transaction ID getter method to other code logic this needs to know the Curr ENT transaction ID.

in a single threaded environment, TransactionManager can simply store the ID as a static field and return as is. However, this would certainly not work in a multiple-threaded environment. Imagine multiple threads is using Transactionmanager–transaction IDs generated by each thread can overwrite all other As there is only one static instance of transaction ID. One may synchronize and blocks other transactions to avoid overwrites, but this would totally defeat the purpose of have Multiple threads.

in order to solve this problem, ThreadLocal provides a very neat solution:

public class transactionmanager {    private static final  Threadlocal<string> context = new threadlocal<string> ();     public static void starttransaction ()  {         //logic to start a transaction        //...         context.set (Generatedid);    }     public static string gettransactionid ()  {         return context.get ();     }    public static  void endtransaction ()  {        //logic to  end a transaction        //...         context.remove ();     }} 

Different thread that starts transactions via TransactionManager would get it own transaction ID stored in the context. Any logic within the same thread can call Gettransactionid () later on to retrieve the value belongs/local to that thread. So problem ' s solved!

The internals of ThreadLocal and how it Works

let's drill down a little bit into the ThreadLocal ' s internals. ThreadLocal is implemented by have a Map (a threadlocalmap) as field (With weakreference entry) within each Th Read instance. (There is actually 2 maps; the second one was used for inheritabelethreadlocal, but let's not complicate the picture). The keys of those maps are the corresponding threadlocals themselves. Therefore, when a set/get was called on a ThreadLocal, it looks at the current thread, find the map, and look up the value With "This" ThreadLocal instance.

Still confused? I certainly am. Let's look at a real example.

    • Code running in Thread 1 calls set () on ThreadLocal instance "A" with value "123″

    • Code running in Thread 2 calls set () on ThreadLocal instance "A" with value "234″

    • Code running in Thread 1 calls set () on ThreadLocal instance "B" with value "345″

And this is the end result:

Thread 1 (the instance) ' s field THREADLOCALMAP (M1) has 2 entries:

Key Value
Threada "123"
Threadb "345"
Thread 2 (the instance) ' s field threadlocalmap (M2) has 1 entry:

Key Value
Threadb "234"

Now if some code logic in Thread 1 calls get () on ThreadLocal instance "A", the ThreadLocal logic would lookup the current Thread, which is instance Thread 1, then access the field threadlocalmap of this Thread instance, which is M1, it can then Lookup the value by using M1.get (this), with ' this ' as ThreadLocal and the result is ' 123″

Now-what-watch out for!

Did I hear weak reference for ThreadLocal entries? Does that mean I don ' t has to clean up? Well, it's not quite.

first of all, the value object is put into the ThreadLocal would not purge itself (garbage collected) if there is no more S Trong references to it. Instead, the Weak reference is do on the thread instance, which means Java garbage collection would clean up the THREADL ocal map If the thread itself is not strongly referenced elsewhere.

So now the question Is:when would the Thread object get garbage collected?

The answer is:it depends, but all assume the thread is long running. 2 Common examples:

    • Servlets. The threads that handle Servlets requests usually stay alive in the container for the lifetime of the server instance. Code logic that uses ThreadLocal might is referenced indirectly by Servlets.

    • Thread pooling java.util.concurrent.Executors. Java encourages recycling threads!

A typical usage of Executor introduced in Java 1.5, if ThreadLocal maps was not cleaned up properly after a transaction is Done, next transactionprocessingtask might inherit values from another previous unrelated task!

Executorservice service = Executors.newfixedthreadpool (ten); Service.submit (new Transactionprocessingtask ());

Be careful with initialization of ThreadLocal, below are an implementation of a counter by Thread. Can what are wrong in the below initialization?

public class Counter {private static threadlocal<integer> Counter = new threadlocal<integer> ();    static {counter.set (0);    } public int Getcountinthread () {return counter.get (); } //...}

the counter would not get initialized correctly! Though the counter is declared as static, it cannot being initialized by has a static initializer, as the initializer only Runs once when the first thread references the Counter class. When the second thread comes in, it does not run Counter.set (0) on that thread, therefore counter.get () returns null Inste Ad of 0! One solution is to Sublcass ThreadLocal and override the InitialValue () method to assign Non-null initial value.

with these in mind, where can probably picture the consequences of not cleaning up after ourselves! An operation, runs on a recycled thread might inherit the values from previous operation on the same thread! Besides, it can also cause memory leaks as the instance stored in ThreadLocal would never get garbage collected if the thre AD is alive.

As a rule of thumb, always clean up/reset your threadlocal after you have finished your "unit of operation"! Even though the current code might is simple enough to bypass the cleanups, it might is adapted and integrated into Servle Ts/thread Pooling later on! After all, cleaning up responsibly are always appreciated both in the realms of programming and real life.





















Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.