Java Source Analysis-Threadlocal__java

Source: Internet
Author: User
Why did you write this article?

A lot of articles on the Internet are talking about the meaning of threadlocal, and then most of them say threadlocal is to solve the thread safety, designed to solve the concurrent security problem, this argument is one-sided, resulting in a lot of people do not understand threadlocal real use What's threadlocal?

Threadlocal translation is a thread-local variable, not a local thread.

Threadlocal is to solve the problem of passing parameters back and forth in a thread, or some resources in different levels of code, but to ensure thread safety without increasing performance loss. Why do you use threadlocal? Single-Resource single-threaded security

For example, we have two modules, one to add resources (static variable) 100, one to reduce the resources by 100, but we do not want to pass the resources through the parameters, we can only set this resource as a static variable.
Single Thread Instance code:

Import Java.util.concurrent.atomic.AtomicInteger;
    public class Incthread implements runnable{private static int VALUE = 0; @Override public void Run () {iscr100 ();//Module 1, add descr100 ();/Module 2, reduce the public void de
            Scr100 () {for (int i = 0; i< 1000; i++) {value--;
            try {//Analog IO, allow CPC to switch thread.sleep (1);  The catch (Interruptedexception e) {}} is public void iscr100 () {for (int i = 0; i< 1000;
            i++) {value++;
            try {//Analog IO, allow CPC to switch thread.sleep (1); The catch (Interruptedexception e) {}}} public static void Main (string[] args) throws Interr
        uptedexception {Incthread myinc = new Incthread ();
        Thread thread = new Thread (MYINC);
        Thread.Start ();
        When the main thread exits, other threads are executed Thread.Sleep (10000); Print Final Results System.out. println (VALUE); }
}

There is no problem with the single thread, and the end result of example value above must be 0. Single resource multithreading is not secure

But if it is multithreading will be correct. We modify the main method and use two threads instead:

    public static void Main (string[] args) throws interruptedexception {
        Incthread myInc1 = new Incthread ();
        Thread thread1 = new Thread (MYINC1);
        Thread thread2 = new Thread (MYINC1);
        Thread1.start ();
        Thread2.start ();
        To ensure that the main thread exits, other threads are executed
        thread.sleep (10000);
        Print final result
        System.out.println (VALUE);
    }

The result of the execution is certainly not 0, because the + + and-operations of int are not thread safe.
Of course, in order to solve this problem, we can set the value into a thread-safe class, such as Atomicinteger, which is unique to the resource can do so, although there is some performance loss, this is no way, but if it is multiple resources, When each thread can be assigned to a resource, using a thread-safe class degrades performance, and if our resources are not thread-safe, such as a database connection. How to secure multi-resource multithreading

This time threadlocal on the stage of history.

Import Java.util.concurrent.atomic.AtomicInteger; public class Incthread implements runnable{private static threadlocal<integer> VALUE = new threadlocal<>
    (); @Override public void Run () {value.set (0);//Initialize the resource, such as getting the database connection pool iscr100 ();//Module 1, add descr100 (
    )//Module 2, Reduce System.out.println (Value.get ()); public void descr100 () {for (int i = 0; i< 1000; i++) {try {integer integer
                = Value.get ();
                integer++;
            Analog IO, allowing CPC to switch thread.sleep (1);  The catch (Interruptedexception e) {}} is public void iscr100 () {for (int i = 0; i< 1000;
            i++) {Integer integer = Value.get ();
            integer--;
            try {//Analog IO, allow CPC to switch thread.sleep (1); The catch (Interruptedexception e) {}}} public static void Main (string[] args) throWS interruptedexception {incthread myInc1 = new Incthread ();
        Thread thread1 = new Thread (MYINC1);
        Thread thread2 = new Thread (MYINC1);
        Thread1.start ();
        Thread2.start ();
    When the main thread exits, other threads are executed Thread.Sleep (10000); }
}

So far, we have explained the meaning of threadlocal, but some people will say that, like this multiple resource synchronization, we can do it ourselves, such as using map, with the thread name as key, with resources as value, the people who proposed this scheme are very intelligent, Threadlocal also does use map as a store, but there are two disadvantages to this scenario.
1. Poor versatility: Each frame's thread name is variable, such as the spring Framework, servlet, and so on, difficult, and no way to have a universal map to achieve this function.
2. Low usability: We implement a set of mechanisms ourselves, it is difficult to use in other people's existing framework, only in our own framework to use.
Then, we have to choose Threadlocal. threadlocal Source Analysis

Since threadlocal is to solve the problem that resources are passed around in multiple resource multithreading, threadlocal must have at least set, get and delete three methods, in fact threadlocal has 5 methods:

descriptors and return values Method Name Description
T Get () Returns the value in the current thread ' s copy of this thread-local variable.
Protected T InitialValue () Returns the current thread's "initial value" for this thread-local variable.
void Remove () Removes the current thread ' s value for this thread-local variable.
void Set (T value) Sets the current thread ' s copy of this thread-local variable to the specified value.
Static <S> threadlocal<s> Withinitial (supplier< extends s> Supplier) Creates a thread local variable.
Set Method
    public void Set (t value) {
        //Get index thread
        T = Thread.CurrentThread () of the current thread;
        Gets the Threadlocalmap
        threadlocalmap map = getmap (t) of the current thread;
        if (map!= null)
            //Set Value
            map.set (this, value);
        else
            //Set value
            Createmap (t, value) for the first time;
    

As you can see, the root cause for threadlocal to get thread resources across the code hierarchy is the static method of Thread.CurrentThread (), so that threadlocal can do anything at any time without having to pass in the thread name or ID.

Let's take a look at what Getmap (t) did.

    Threadlocalmap Getmap (Thread t) {return
        t.threadlocals;
    }

And the thread class has a member variable:
Threadlocal.threadlocalmap threadlocals = null;
Then we can understand that the resources stored in threadlocal are actually stored on thread, threadlocal just as an index to find the resource. Get () method

We know that the Threadlocal instance is the index of the current resource, then the source of the Get () method comes into being.

    Public T get () {
        Thread t = thread.currentthread ();
        Gets the Threadlocalmap
        threadlocalmap map = getmap (t) of the current thread;
        If the map exists,
        if (map!= null) {
            //Get to resource
            threadlocalmap.entry e = Map.getentry (this);
            if (e!= null) {
                @SuppressWarnings ("unchecked")
                T result = (t) e.value;
                return result;
            }
        Returns the initialized value return
        Setinitialvalue () when the map does not exist or does not have a set resource
    

Setinitialvalue method Definition:

    Private T Setinitialvalue () {
        T value = InitialValue ();
        Thread t = thread.currentthread ();
        Threadlocalmap map = getmap (t);
        if (map!= null)
            Map.set (this, value);
        else
            createmap (t, value);
        return value;
    }

If the get resource does not exist, the InitialValue () method is eventually invoked and the resource is initialized:

    Protected T InitialValue () {return
        null;
    }

But this method will eventually return null, so if we set the resource, if call get will return null directly. withinitial () static method

In order to avoid getting to NULL, we also need to judge whether NULL is initialized threadlocal,threadlocal provides us with a static method that can be passed into a function to initialize the threadlocal.

    public static <S> threadlocal<s> withinitial (supplier<. extends s> Supplier) {return
        new suppliedthreadlocal<> (supplier);
    }
Remove () method

Remove () is relatively simple, here is not introduced.

     public void Remove () {
         Threadlocalmap m = Getmap (Thread.CurrentThread ());
         if (M!= null)
             ///When the threadlocalmap of the thread exists, delete the resource.
             M.remove (this);
     }
last

Finally, we conclude with an official explanation. Threadlocal:
Threadlocal provides thread-local variables that are not the same as ordinary variables because each thread's threadlocal has its own copy and is a separate initialized copy , other threads are inaccessible. Using threadlocal is usually a private static field in the thread-associated class, such as a user ID and a transaction ID.

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.