Java Foundation-threadlocal

Source: Internet
Author: User

Let's talk about the implementation of Threadlocal and its memory leak problem

Let's start with an official example, where a ThreadID class is constructed to hold the respective ID in each thread, which is globally unique and can be obtained by getting the ID.

1     Private Static classThreadId {2         //Atomic integer containing the next thread ID to be assigned3         Private Static FinalAtomicinteger NextID =NewAtomicinteger (1);4         //thread local variable containing each Thread ' s ID5         Private Static FinalThreadlocal<integer> threadId =NewThreadlocal<integer>() {6 @Override7             protectedInteger InitialValue () {8                 returnnextid.getandincrement ();9             }Ten         }; One         //Returns The current thread ' s unique ID, assigning it if necessary A          Public Static intget () { -             returnthreadid.get (); -         } the}

The constructor of the threadlocal is an empty function, and the only operation of the new Threadlocal instance is the initialization of the Threadlocalhashcode, which is obviously a hash value, and the subsequent use of the map is assumed.

1 Private Final int threadlocalhashcode = Nexthashcode ();

And see what happens when I call get.

/*** 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 (); //thread has an instance field of type Threadlocalmap, getting the threadlocalmap of the current thread is actually returning t.threadlocalsThreadlocalmap map =Getmap (t); if(Map! =NULL) {            //take the current threadlocal instance as key to get the entryThreadlocalmap.entry e = Map.getentry ( This); if(E! =NULL) {@SuppressWarnings ("Unchecked")                //get the value in entryT result =(T) E.value; returnresult; }        }        //if the current thread's threadlocalmap is null, or if the current threadlocal has not yet been inserted into Threadlocalmap, the initialization is done by initializing the map, calling the custom InitialValue method, Wrap the InitialValue return value into a entry insert map        returnSetinitialvalue (); }

Look at the structure of the map.

1     Static classThreadlocalmap {2         ......3         Static classEntryextendsWeakreference<threadlocal<?>> {4             /**The value associated with this ThreadLocal.*/5 Object value;6 7Entry (threadlocal<?>K, Object v) {8                 //Note that the key here is packaged as a weakreference9                 Super(k);TenValue =v; One             } A         } -         ...... -         Privateentry[] table; the         ...... -         PrivateEntry Getentry (threadlocal<?>key) { -             //Threadlocalhashcode is generated at threadlocal initialization and is globally unique. Here -             inti = Key.threadlocalhashcode & (table.length-1); +Entry e =Table[i]; -             if(E! =NULL&& e.get () = =key) //e.get () is obtained from the WeakReference threadlocal  +                 returne; A             Else at                 //interesting, the general hash table uses a chain structure to solve the hash conflict, and here when the hash conflict in the linear detection -                 returnGetentryaftermiss (Key, I, e); -         } -         ...... -}

The question comes, why entry in the key to be packaged into WeakReference?

Imagine that when we no longer need to threadlocal, the previous example is the ThreadID class variable threadid is null (assuming ThreadID is not final, and no other reference), The Threadlocalmap in the thread class still holds the ThreadID reference, which results in a memory leak. The threadlocal is packaged as a weakreference as a key store, and when ThreadID is null, the threadlocal is recycled when it is in the GC, but at this point the value is still there, Threadlocal will remove key null value while other operations are in progress. There is a hidden memory leak , and if you do not perform the threadlocal operation later, the value will not be released. Usually we need a variable declared as threadlocal, which is not expected to be recycled during operation, so we will usually declare it as static final and, if there is a need for recycling, use the threadlocal remove for display release.

Java Foundation-threadlocal

Related Article

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.