ThreadLocal usage Analysis

Source: Internet
Author: User
Tags thread class
1. Overview

What is threadlocal? In fact, Threadlocal is not a local implementation version of a thread, it is not a threaded, but a threadlocalvariable (thread local variable). Perhaps it would be more appropriate to name it Threadlocalvar. The thread local variable (ThreadLocal) function is very simple, that is, for each thread that uses the variable to provide a copy of the value of a variable, is a special thread binding mechanism in Java, is that each thread can independently change its own copy, and does not conflict with the copy of other threads.

From a thread's point of view, each thread maintains an implicit reference to a copy of its thread's local variables, as long as the thread is active and the threadlocal instance is accessible, and all copies of its thread's local instance are garbage collected after the threads have disappeared (unless there are other references to those replicas).

The data accessed through threadlocal is always related to the current thread, that is, the JVM binds the private local instance access space for each running thread, thus providing an isolation mechanism for concurrent access problems that often occur in multithreaded environments.

Threadlocal is how to maintain a copy of a variable for each thread. In fact, the idea of implementation is simple, there is a map in the Threadlocal class that stores a copy of each thread's variable.

To sum up, for the problem of multi-thread resource sharing, the synchronization mechanism adopts the way of "time-changing Space", and threadlocal adopts the way of "changing time by Space". The former provides only one copy of the variable, allowing different threads to queue access, and the latter provides a variable for each thread, so it can be accessed at the same time without affecting each other.
2. How to use

Import Java.util.Random; /** * threadlocal Use Process * 1. Create an Threadlocal instance object to hold objects between threads that need to be quarantined * 2. Create a method that get*** gets the object, as follows Getstudent () * 3. In the thread's Run method, use GE t*** gets the object, manipulate this object to * or * 2. Override the InitialValue method to set the initial value * 3.tlocal.get*** to get the original object * @author ISC1 * * */public class Threadloca
	
	Ltest implements Runnable {threadlocal<student> studentlocal = new threadlocal<student> (); ① Specifies the initial value threadlocal<student> tlocal = new threadlocal<student> () by overriding the ThreadLocal InitialValue () method with an anonymous inner class
			{@Override protected Student InitialValue () {Student s = new Student (10);			
		return s;
	
}
	}; Public Student getstudent () {//Student s = (Student) studentlocal.get ();//if (s = = null) {//s = new Student ()
;
Studentlocal.set (s);
}//return s;
		} public static void Main (string[] args) {threadlocaltest t = new threadlocaltest ();
		New Thread (T, "T1"). Start ();
	New Thread (T, "T2"). Start (); } private void Accessstudent () {//Student s =this.getstudent ();
		Student s = tlocal.get ();
		Random random = new random ();
		int age = Random.nextint (100);
		System.out.println ("Current thread set age" + thread.currentthread () + ":" + age);
		S.setage (age);
		System.out.println ("Current thread first get age" + thread.currentthread () + ":" + s.getage ());
		try {thread.sleep (500);
		} catch (Interruptedexception e) {e.printstacktrace ();
	} System.out.println ("Current thread second get age" + thread.currentthread () + ":" + s.getage ());
		} class Student {Student (int age) {this.age=age;

		} Student () {} private int age;
		public int getage () {return age;
		} public void Setage (int age) {this.age + = age;

	}} @Override public void Run () {accessstudent (); }}<span style= "color: #cc0000;" > </span>

There are annotations in the code, there is not much to explain, the comment part is not useless, but the first implementation method, both can ~ source program originates from the network. Reference Link: Portal

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. Introduction to the principle

The Get () method is used to get a copy of the variable that threadlocal holds in the current thread, set () to make a copy of the variable in the current thread, and remove () to remove the copy of the variable in the current thread, InitialValue () is a protected method, is typically used to rewrite when used, it is a lazy loading method,

First of all Within each thread, there is a member variable threadlocals of type Threadlocal.threadlocalmap, which is used to store the actual copy of the variable, the key value is the current threadlocal variable, and value is a copy of the variable ( 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.

Source Analysis See links
4. Memory leak problem < original view >

Threadlocal uses a map with a weak reference, and when the strong reference to Threadlocal is released, the value in the map is not recycled. And this value will never be accessed. So there is a memory leak. The best practice is to call the Threadlocal Remove method.

These references exist in the life cycle of the threadlocal. Look at the following image: Solid lines represent strong references, and dashed lines represent weak references.

There is a map in each thread, and the type of map is Threadlocal.threadlocalmap. The key in map is a threadlocal instance. This map does use a weak reference, but the weak reference is only for key. Each key has a weak reference to threadlocal. When the Threadlocal instance is set to NULL, no strong references point to the threadlocal instance, so threadlocal will be reclaimed by GC. However, our value cannot be recycled because there is a strong reference that is connected from the current thread. The current thread will not exist on the stack, the strong reference will be broken, and now thread, MAP, and value are all recycled by GC.

So it comes to the conclusion that as long as this thread object is recycled by GC, there will be no memory leaks, but when threadlocal is set to null and the thread ends this time it will not be recycled, we think of a memory leak. In fact, this is a conceptual understanding of the inconsistency, there is no good argument. The most deadly is the case where the thread object is not recycled, and this has a real memory leak. For example, when using a thread pool, the end of threads will not be destroyed and will be used again. A memory leak can occur.

Ps. In order to minimize the likelihood and impact of memory leaks, Java will erase all key null value in thread map when Threadlocal Get,set. So the most feared situation is that the Threadlocal object is set to NULL, start a "memory leak", and then use the thread pool, the threads end, the thread is put back into the thread pool is not destroyed, the thread has not been used, or allocated to use and no longer call the Get,set method, Then there will be a real memory leak during this period. <>

The most common threadlocal usage scenarios are used to resolve database connections, session management, date formatting, and so on.

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.