Summary of question and answer form:
1, the role of the Threadlocal class
The role of threadlocal is to provide local variables within threads that can guarantee the independence of variables in various threads when accessed in a multithreaded environment.
ThreadLocal is used to save a thread shared variable: For the same static ThreadLocal, different threads can only get,set,remove their own variables from it, without affecting the variables of other threads.
1. Threadlocal.get: Gets the value of the current thread shared variable in ThreadLocal.
2. Threadlocal.set: Sets the value of the current thread share variable in ThreadLocal.
3. Threadlocal.remove: Removes the value of the current thread shared variable in ThreadLocal.
4, ThreadLocal.initialValue:ThreadLocal is not assigned a value by the current thread, or the current line Cheng gang call the Remove method after calling the Get method, return this method value.
2, threadlocal principle, how is threadlocal realized?
First, within thread thread There is a member variable threadlocals of type Threadlocal.threadlocalmap, this threadlocals is used to store the actual variable copy, the key value is the current threadlocal variable, value is a variable copy (that is, a variable of type T).
Initially, in thread, Threadlocals is empty, and when the Get () method or set () method is called through the threadlocal variable, the threadlocals in the thread class is initialized. And with the current threadlocal variable as the key value, to threadlocal the copy variable to save as value, save to Threadlocals.
Then in the current thread, if you want to use a copy variable, you can find it in the threadlocals by using the Get method.
To summarize:
1) The actual copy created through threadlocal is stored in each thread's own threadlocals;
2) Why the Threadlocals type Threadlocalmap's key value is Threadlocal object, because there can be more than one threadlocal variable in each thread, just like longlocal and stringlocal in the code above;
3) before the GET, must first set, otherwise it will report null pointer exception;
You must override the InitialValue () method if you want to have normal access without calling set before get.
Because in the above code analysis process, we found that if there is no first set, that is, the map can not find the corresponding storage, then by calling the Setinitialvalue method to return I, and in the Setinitialvalue method, there is a statement is t value = InitialValue (), and by default, the InitialValue method returns NULL.
3, threadlocal of the use of the scene
The most common threadlocal usage scenarios are used to resolve database connections, session management, and so on.
Such as:
Private Static threadlocal<connection>new threadlocal<connection>() {public Connection InitialValue () { return drivermanager.getconnection (db_url); publicstatic Connection getconnection () { return Connectionholder.get (); }
The following code is excerpted from:
http://www.iteye.com/topic/103804
Private Static FinalThreadLocal threadsession =NewThreadLocal (); Public StaticSession getsession ()throwsinfrastructureexception {Session s=(Session) threadsession.get (); Try { if(s = =NULL) {s=getsessionfactory (). Opensession (); Threadsession.set (s); } } Catch(Hibernateexception ex) {Throw NewInfrastructureexception (ex); } returns;}
4, often said threadlocal memory leak problem:
Static Class Entry extends Weakreference<threadlocal<?>> {/** The value associated with this ThreadLocal. */ Object value; Entry (threadlocal<?> K, Object v) { super (k); Value = V; } }
From the above source can be seen, threadlocalmap use ThreadLocal weak reference as entry key, if a ThreadLocal no external strong reference to reference it, the next time the system GC, this ThreadLocal will inevitably be recycled, so that Threadlocalmap will appear with key null entry, there is no way to access the value of these key null entry.
In the get, set, and remove methods we have described above, the key null entry will be cleared (Expungestaleentry method, the value of entry is emptied, and the entry will be completely recycled when the next garbage collection).
However, if the current thread is running and does not execute the GET, set, remove methods all the time, the value of these key null entry will always be a strong reference practice: ThreadRef, Thread- Threadlocalmap, Entry, value, causes the value of these key null Entry to never be reclaimed, causing a memory leak.
How do I avoid memory leaks?
To avoid this situation, we can manually call the Remove method after threadlocal is used to avoid a memory leak.
5. Other Summary
Summarize:
- Each thread has a threadlocalmap type of Threadlocals property.
- The Threadlocalmap class is equivalent to a map,key is the ThreadLocal itself, value is our values.
- When we pass Threadlocal.set (new Integer (123)); , we put a key-value pair in the Threadlocals attribute in this thread, and key is the threadlocal,value of the Threadlocal.set (new Integer (123)), which is the value new Integer (123).
- When we pass the Threadlocal.get () method, we first get the Threadlocals property of this thread based on this thread, and then because this property is a key-value pair, we can get the value according to the key threadlocal. Note that this time the key threadlocal is the same as the key threadlocal when we set the method, so we can get the same value.
- Threadlocalmap's get/set/remove approach is essentially the same as HashMap's internal implementation, through "Key.threadlocalhashcode & (Table.length-1)" The formula calculates the index position we want to find, and if the key value pair for that index is not what we are looking for, the next index position is computed by the Nextindex method until the target key value pair is found or empty.
- Hash conflict: Elements at the same index position in HashMap are kept in the same index position in a linked list, whereas in Threadlocalmap, the data structure of the linked list is not used, but instead (the current index position + 1) The result of the length modulus as the location of the same index element: The Nextindex method in the source code, you can achieve the following formula: If I is the current index position, then the next index position = (i + 1 < len)? i + 1:0.
————— END —————
Reference article: 1, Java Concurrency: threadlocal detailed (Joonwhee)
2, Java concurrent Programming: in-depth analysis threadlocal (Haizi)
Java concurrency Programming: in-depth anatomy of threadlocal (summary)