Java ThreadLocal Use of detailed

Source: Internet
Author: User

Threadlocal's official API is interpreted as:

"This class provides thread-local (thread-local) variables. These variables are different from their ordinary counterparts, because each thread that accesses a variable (through its Get or set method) has its own local variable, independent of the initialized copy of the variable. ThreadLocal instances are typically private static fields in a class that want to associate the state with a thread (for example, a user ID or transaction ID). "

The approximate meaning is two points:

    1. Threadlocal provides a special way to access a variable: The variable that is accessed belongs to the current thread, that is, the variable is guaranteed for each thread, and the variable that the same thread gets at any place is consistent, which is called thread isolation.
    2. If you want to use threadlocal, which is usually defined as the private static type, it seems to me best to define the private static final type.
Application Scenarios

Threadlocal commonly used to share data, when you want to use a variable in multiple methods, this variable is the state of the current thread, the other threads do not rely on this variable, the first thing you think of is to define the variables within the method, and then pass parameters between the methods to use, this method can solve the problem, But the annoying thing is that every method needs to declare formal parameters, declare multiple places, and call multiple places. affect the aesthetics and maintenance of the code. Is there a way to access variables like private static? This can be used anywhere in the class. This time threadlocal.

Practice

Let's first look at a piece of code

 PackageCom.test1;ImportJava.util.HashMap;ImportJava.util.Map; Public classTest1ImplementsRunnable {Private Final StaticMap map =NewHashMap (); intID; /*static threadlocal*/     PublicTest1 (intID) {Super();  This. ID =ID; } @Override Public voidrun () {//map map = Threadlocal.get ();         for(inti = 0; I < 20; i++) {Map.put (I, I+ ID * 100); Try{Thread.Sleep (100); } Catch(Exception ex) {}} System.out.println (Thread.CurrentThread (). GetName ()+ "# map.size () =" + map.size () + "#" +map); }     Public Static voidMain (string[] args) {thread[] runs=NewThread[15]; Test1 T=NewTest1 (1);  for(inti = 0; i < runs.length; i++) {Runs[i]=NewThread (t); }         for(inti = 0; i < runs.length; i++) {Runs[i].start (); }    }}

This program is intended to start 15 threads, the thread writes 20 integer values to the map, and then outputs a map. Running the program and observing the results, we can see that there are more than 20 elements in the map, which indicates that the program has a thread-safety problem.

We all know that HashMap is non-thread-safe, the program starts 15 threads, they share the same map,15 thread to write to the map object, which is bound to cause thread security problems.

We have two ways to solve this problem:

    1. Put the map's declaration into the run method, so that map becomes the method internal variable, each thread has a copy of New HashMap (), no matter how many threads execute the Run method, no thread security issues. This method, as mentioned in the application scenario, is a nuisance if there are multiple places to use map.
    2. Replace the HashMap with Hashtable. With thread synchronization to solve the problem, but our program just want to write to a map 20 integer key-value only, do not need to thread synchronization, synchronization will inevitably affect performance, not worth the candle.
    3. Threadlocal provides another solution, which is to bind the instance variable from new HashMap () to the current thread, above solution A. This variable can then be obtained from threadlocal from anywhere. Restore the comment code in the program, and then the private final static map map = new HashMap (); Comment out, run the program, the result is what we want.
Implementation principle

The program calls the Get () method, let's look at the source code of the method:

public == getmap (t); if NULL  = map.getentry (this); if NULL )return  (T) e.value;} return setinitialvalue ();}

Source code for the Getmap method:

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

This method returns the Threadlocalmap instance in the current thread. Read the thread source code we found that thread has the following variable declaration:

/**/null;

For the time being, we can understand threadlocalmap as a map-like class and then explain it.

The general meaning of the Get () method is to get an instance of Threadlocalmap from the current thread threadlocals, if threadlocals is not empty, Then take the current threadlocal instance as key to get the corresponding value from the threadlocals. If it is not, then the Setinitialvalue () method is called to initialize the Threadlocals, and the return value of the InitialValue () method is eventually returned. Here is the source code for the Setinitialvalue () method

Private== = Getmap (t); if NULL ) Map.set (this, value); Else Createmap (t, value); return value;}

We see Map.set (this, value), which takes the Threadlocalmap instance as a key, and InitialValue () returns the return value as Value,set to Threadlocals.

The program InitialValue () and returns value when declaring the Threadlocal instance, and of course we can call the set (T T) method to set value directly. Here is the source code for the set (T-T) method:

 Public void  == getmap (t); if NULL ) Map.set (this, value); Else Createmap (t, value);}

We see that it has a return statement that is less than the Setinitialvalue () method. Both of these methods can achieve the effect of initializing the Threadlocalmap instance.

Let's take a look at the structure of the Threadlocal class.

The Threadlocal class has only three properties, as follows:

/*the hash value of the threadlocal, which map uses to store the value*/Private Final intThreadlocalhashcode =Nexthashcode ();/*The class can update the int value atomically, which is mainly used to generate a new hash value when a new threadlocal instance is generated, and map uses that value to store the object*/Private StaticAtomicinteger Nexthashcode =NewAtomicinteger ();/*the variable identifies the increment of the hash value each time a new threadlocal instance is generated*/Private Static Final intHash_increment = 0x61c88647;

The rest is some way. The key point is that threadlocal defines a static inner class Threadlocalmap. We will analyze this class again in the next section. From the Threadlocal class structure, we can see that actually the key to the problem is that threadlocalmap,threadlocal just provides the function of management, and we can say threadlocal just acting threadlocalmap.

Threadlocalmap Source Code Analysis

Since Threadlocalmap implements a map-like function, let's start by looking at its set method source code:

Private voidset (ThreadLocal key, Object value) {//We don ' t use a fast path as with get () because it 's at//least as common to use Set () to create new entries as//it is-to-replace existing ones, in which case, a fast//path would fail more often than not.entry[] Tab=table;intLen =tab.length;inti = Key.threadlocalhashcode & (len-1);  for(Entry e =tab[i];e!=NULL; e= Tab[i =Nextindex (i, Len)]) {ThreadLocal k=e.get ();if(k = =key) {E.value=value;return;} if(k = =NULL) {replacestaleentry (key, value, I);return;}} Tab[i]=NewEntry (key, value);intSZ = + +size;if(!cleansomeslots (i, SZ) && sz >=threshold) rehash ();}

The main function of this method is to talk about Key-value storage in Threadlocalmap, where at least we see that key is actually Key.threadlocalhashcode,threadlocalmap also maintains the entry array, which we will explain in the next section entry. This involves the processing of a hash conflict, which does not conflict with HashMap as a list of links to be added later. If you are interested in this hash conflict resolution, you can further study the source code.

Since Threadlocalmap is also using entry to store objects, let's take a look at the entry class declaration, entry is defined inside the Threadlocalmap:

Static class extends Weakreference<threadlocal> {/***/Object value; Entry (ThreadLocal K, Object v) {super= V;}}

Here we see that entry integrates the WeakReference class, which declares the threadlocal that each entry object retains a weak reference to the Threadlocal instance, and the reason for doing so is that After the thread finishes, it needs to remove the threadlocal instance from the map to reclaim the memory space.

Summarize

First, Threadlocalmap is not designed to solve thread-safety problems, but rather provides a mechanism for binding instances to the current thread, similar to the effect of isolation, and actually the new variable in the method can achieve similar results. Threadlocalmap and thread security basically do not take sides, bound instances are not multithreaded common, but each thread new, this instance is certainly not common, if shared, it will lead to thread safety issues. The greatest use of threadlocalmap is to share the instance variable as a global variable, which can be accessed in any method of the program. Many people on the internet say Threadlocalmap is the solution to the thread safety problem, in fact, is words too literally, the two are not similar problems.

Java ThreadLocal Use of detailed

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.