"Original" Source angle analysis Android message mechanism series (iii) how--threadlocal works

Source: Internet
Author: User

ι Copyright Notice: This article for Bo Master original article, without Bo Master permission not reproduced.

First look at the definition of threadlocal in Android source code (API24):

 Public class

That is, Threadloca is a generic class, and then look at the comment on that class:

/** * This class provides thread-local variables. These variables differ from * their normal counterparts in so each thread this accesses one (via its * <tt>get<  /tt> or <tt>set</tt> method) has its own, independently initialized * copy of the variable. <tt>ThreadLocal</tt> instances is typically private * static fields in classes, wish to associate State W ith a thread (e.g., * A user ID or Transaction ID). * * <p>for example, the class below generates unique identifiers local to each * thread. * A thread ' s ID is assigned the first time it invokes <tt>threadid.get () </tt> * and remains unchanged on subse Quent calls. * <pre> * Import Java.util.concurrent.atomic.AtomicInteger; * public class ThreadId {*//Atomic integer containing the next thread ID to be assigned * private static FINA L Atomicinteger nextid = new Atomicinteger (0); * *//thread local variable containing each thread ' s ID * private static Final threadlocal&lt;integer> threadId = * New Threadlocal&lt;integer> () {* & #64; Ove Rride protected Integer InitialValue () {* return nextid.getandincrement (); *} *}; * *//Returns The current thread's unique ID, assigning it if necessary * public static int Get () {* RET Urn Threadid.get (); *} *} * </pre> * <p>each thread holds an implicit reference to its copy of a thread-local * variable as Long as the thread is alive and the <tt>ThreadLocal</tt> * instance are accessible; After a thread goes away, all of its copies of * Thread-local instances is subject to garbage collection (unless other * References to these copies exist).  * *@authorJosh Bloch and Doug Lea *@since1.2*/

That is, the Threadlocal class provides a variable of thread-local, but the copy of the variable in each thread is different, and each thread uses the thread-local variable independently of the copy in its own thread. The instance of threadlocal is private static, and the instance is related to the state of a thread. Each thread holds a weak reference to the thread-local variable. A thread dies, and a copy of all thread-local instances in the thread is recycled by the GC (unless there are some other references to the replica.) Because the GC reclaims an object as a criterion, there is no reference or referenced relationship to the object.

Just figure out the get and set methods of threadlocal, and you can see how it works.

First look at the set method, the source code is as follows:

    /*** Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses would have a no need to * override this method, and relying solely on the {@link#initialValue} * method to set the values of Thread-locals. *     * @paramValue the value to is stored in the current thread's copy of * this thread-local. */     Public voidset (T value) {Thread T=Thread.CurrentThread (); Threadlocalmap Map=Getmap (t); if(Map! =NULL) Map.set ( This, value); ElseCreatemap (t, value); }

Value is the data to be stored. Threadlocalmap is an internal class in threadlocal that is used primarily to store data in Threadlocal, which is described in detail below. With this code, we can see that the set method first gets the threadlocalmap of the current thread. If the map is not empty, the data is updated directly; otherwise, the Threadlocalmap is created and the value values are placed in the map.

If you want to give the thread-local variable an initial value, you do not need to rewrite the set method, directly rewrite the InitialValue method.

protected T InitialValue () {    returnnull;}

In general, the method is called the first time when the Get method is called, unless the set method is called before the Get method is called.

Let's take a look at the Threadlocalmap:

    /**      * Threadlocalmap is a customized hash map suitable only for     * maintaining thread local values. No Operations is exported     * Outside of the ThreadLocal class. The class is package private to * allow declaration of the fields in     class Thread.  To help deal     with * very large and long-lived usages, the hash table entries use     * weakreferences for keys.  However, since reference queues is not     * used, stale entries is guaranteed to being removed only when     * the table Starts running out of space.      */    Static class Threadlocalmap

Threadlocalmap is a static inner class in threadlocal, a hash map that is deliberately customized to maintain data in threadlocal. The entry in Hash table uses a weak reference. Because there is no reference queue, it is only possible to remove the entry if there is no space in the hash table.

Threadlocalmap also has a static inner class:

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

Entry.value is the data we store.

Private Entry[] table;

We have stored the entry of the data in that table. The management of the table is then managed to manage the stored data.

Then look at the Get method in Threadlocal:

 public   T get () {Thread T  = Thread.CurrentThread ();     Threadlocalmap map  = Getmap (t);  if  (Map! = null   = map.getentry (this  );  if  (E! = null  )  return       (T) E.value;  return   Setinitialvalue ();}  

Through the source code, we can know that the Get method is to get Threadlocalmap, if Threadlocalmap is not empty, then get its internal entry, by the above analysis of the set method can be known, entry in the way of weak references to store value. If entry is not empty, we return the value in the entry directly to get the data stored in the threadlocal, otherwise, the initialization data in Threadlocal is returned.

From the analysis of the set and get methods on the face of threadlocal, we can see that we are always working on the threadlocalmap of the current thread, storing the data in entry, and storing a lot of entry in the table, managing the entry, The table array is also threadlocalmap the current thread, so when we access the same threadlocal set and get methods in different threads, they have read/write operations on the threadlocal only inside the respective thread. This explains why Threadlocal can store and modify data on multiple threads in a non-disruptive way.

"Original" Source angle analysis Android message mechanism series (iii) how--threadlocal works

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.