Talk about threadlocal principle and use scene-java 8 source code

Source: Internet
Author: User

I believe many people know that threadlocal is for each thread, but the principle of which we believe that we are not very clear, then we will look at the source code.

First, let's look at its set method. Very simple, get the map from the current thread. So what does this getmap method look like? Let's keep looking.

/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses'll has no need to
* Override this method, relying solely on the {@link #initialValue}
* method to set the values of Thread-locals.
*
* @param value of the value to being stored in the current thread ' s copy of
* This thread-local.
*/
public void Set (T value) {
Thread t = Thread.CurrentThread ();
Threadlocalmap map = getmap (t);
if (map! = null)
Map.set (this, value);
Else
Createmap (t, value);
}

Gets the threadlocals of the single-money thread from the current thread. Follow up on t.threadlocals.

/**      * Get The map associated with a ThreadLocal. Overridden in     * inheritablethreadlocal.     *     @param  T     the current thread@return the map     */      threadlocalmap getmap (Thread t) {        return  t.threadlocals;    }

This threadlocals is defined in thread, which is the maintainer's own threadlocals inside each thread, so that each thread is independent. Thinking back again on the set method above, if map is not NULL, then re-set operation, if empty, you need to create this threadlocalmap. Let's see how the creation is done.

/* ThreadLocal values pertaining to this thread. This map is maintained     *    /null;

Here is the process of creating, there is a static inner class in Threadlocalmap, the static inner class is the same as the normal class, and the static properties and methods are not the same as the static inner classes , which we should pay attention to. First, based on the current instance of Threadlocal, get the current hashcode and then again with (initial capacity-1) result for 7,entry is the static inner class of Threadlocalmap, type is a weak reference , that is, If the key inside is null, the value is the expired value, and the subsequent erase will be erased.

/**
* Create the map associated with a ThreadLocal. Overridden in
* Inheritablethreadlocal.
*
* @param t the current thread
* @param firstvalue value for the initial entry of the map
*/
void Createmap (Thread T, T firstvalue) {
T.threadlocals = new Threadlocalmap (this, firstvalue);
}


/*** Construct A new map initially containing (Firstkey, firstvalue). * Threadlocalmaps is constructed lazily, so we had create * one when we had at least one entry to put in it. */Threadlocalmap (ThreadLocal<?>Firstkey, Object firstvalue) {Table=NewEntry[initial_capacity]; inti = Firstkey.threadlocalhashcode & (initial_capacity-1); Table[i]=NewEntry (Firstkey, firstvalue); Size= 1; Setthreshold (initial_capacity); }/*** The entries in this hash map extend WeakReference, using * It main ref field as the key (which is Always a * ThreadLocal object). Note that null keys (i.e. entry.get () * = = NULL) mean that the key is no longer referenced, so the * entry Can is expunged from table. Such entries is referred to * as "stale entries" in the code that follows. */ Static classEntryextendsWeakreference<threadlocal<?>> { /**The value associated with this ThreadLocal.*/Object value; Entry (ThreadLocal<?>K, Object v) { Super(k); Value=v; } }

Just now if the map is empty, re-create a threadlocalmap assignment to the current thread, if the current thread map is not empty, then you need to get the current Threadlocalmap, and then re-set the value.

This is its set method, so let's look at a get method, get the current thread, and get threadlocalmap from thread, and then take out the value in it, if we don't find the map, Initializes an instance of key threadlocal into the threadlocalmap in the current thread, and sets value to NULL. Finally, NULL is returned to the Get method.

 /*** Returns the value in the current thread's copy of this * thread-local variable. If the variable have no value for the ' current thread ', it is first initialized to the value returned * by an INVOC ation of the {@link#initialValue} method. *     * @returnThe current thread ' s value of this thread-local*/     PublicT Get () {Thread T=Thread.CurrentThread (); Threadlocalmap Map=Getmap (t); if(Map! =NULL) {threadlocalmap.entry e= Map.getentry ( This); if(E! =NULL) {@SuppressWarnings ("Unchecked") T result=(T) E.value; returnresult; }        }        returnSetinitialvalue (); }

This is basically the way the content is so much, so what is the scenario we use?

Generally in Web applications context can be used. For example, SimpleDateFormat is non-thread safe, so we can use this class to process, in order to display different formats. I wrote an example for myself as follows:

 PackageCom.hqs;ImportJava.text.SimpleDateFormat;Importjava.util.Date;/*** Created by Huangqingshi on 2018/1/14.*/ Public classThreadlocalexample {//SimpleDateFormat is not thread-safe    Private Static FinalThreadlocal<simpledateformat> ThreadLocal =NewThreadlocal<simpledateformat>() {@OverrideprotectedSimpleDateFormat InitialValue () {return NewSimpleDateFormat ();    }    };  Public Static voidMain (string[] args) {SimpleDateFormat SDF=Threadlocal.get (); Sdf.applypattern ("Yy/mm/dd"); System.out.println (Sdf.format (NewDate ())); Sdf.applypattern ("Mm/dd/yyyy"); System.out.println (Sdf.format (NewDate ())); }}

18/01/14
01/14/2018

Process finished with exit code 0

There are a few things to note when using this threadlocal:

If you define a number of thread variables, you may not be able to create the thread's exception, because some Web server for threads will define the thread pool, when using threadlocal to create a lot of threads, processing time is relatively long, then these threads will not be released, the result will cause the stack overflow, The program is not responding. At this point you need to be aware that the current thread processing is done as much as possible.

There may be perm overflow, such as threadlocal inside a few static classes, then the static class initialization will be in the permanent generation, and will not be released, then the number of objects created will cause the thread to appear this total exception, Then we need to do a remove operation in this case. This does not happen if there are some basic types of threadlocal inside.

Another situation is that if the objects in the thread require data sharing, the threadlocal is set to a static variable.

Well, for this piece of content analysis and collation is so much, if you have any questions, please tell ~ thank you.

Talk about threadlocal principle and use scene-java 8 source code

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.