The difference between ThreadLocal shared thread local variables and thread synchronization mechanism is that threadlocal threads

Source: Internet
Author: User

The difference between ThreadLocal shared thread local variables and thread synchronization mechanism is that threadlocal threads

ThreadLocal is a good idea to solve the thread security problem. It solves the conflict of variable concurrent access by providing an independent variable copy for each thread. In many cases, ThreadLocal is easier and more convenient than directly using synchronized synchronization mechanism to solve thread security problems, and the result program has higher concurrency.

For multi-threaded resource sharing, the synchronization mechanism adopts the "time-for-space" approach, while ThreadLocal adopts the "space-for-time" approach. The former provides only one copy of the variable, allowing different threads to queue for access, while the latter provides a copy of the variable for each thread. Therefore, the former can be accessed simultaneously without affecting each other.

ThreadLocal cannot replace the synchronization mechanism. The two have different problem fields.

1: The synchronization mechanism is used to synchronize concurrent access from multiple threads to the same resource and to facilitate communication between multiple threads;

2: threadLocal isolates data sharing among multiple threads, and does not share variables among multiple threads at all. Therefore, synchronization between multiple threads is not required.

import java.util.Random;public class ThreadSocpeShareData {static ThreadLocal<Integer> t = new ThreadLocal<Integer>();     public static void main(String[] args) {     for(int i=0;i<3;i++){     new Thread(new Runnable() {        @Override    public void run() {       int  data = new Random().nextInt();             System.out.println(Thread.currentThread().getName() +" has put "+ data);          t.set(data);        MyThreadScopeData.getInstance().setName("name" + data);        MyThreadScopeData.getInstance().setAge("age"+data);    new A().get();    new B().get();    }    }).start();     }}         static class A{     public void get(){     int  data = t.get();     MyThreadScopeData myData = MyThreadScopeData.getInstance();     System.out.println("A " + Thread.currentThread().getName() +" "+ data + myData.getAge() + myData.getName()   /*ms.getName()*/);     }     }     static class B{     public void get(){     int  data = t.get();     System.out.println("B " + Thread.currentThread().getName()+ " "+ data);     }     }}class MyThreadScopeData{private MyThreadScopeData(){}private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();public static MyThreadScopeData getInstance(){MyThreadScopeData instance = map.get();if(instance == null){instance = new MyThreadScopeData();map.set(instance);}return instance;}private String name;private String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}}

In fact, the set variables in ThreadLocal are not stored by ThreadLocal, but stored by the Thread object itself. When the user calls the set (Object o) of the ThreadLocal Object, this method uses the Thread. currentThread () gets the current Thread and stores the variables into a Map in the Thread. The Map Key is the current ThreadLocal instance. Please refer to the source code. This is the two main functions. We can see the call relationship between ThreadLocal and Thread:
public void set(T value) {      Thread t = Thread.currentThread();      ThreadLocalMap map = getMap(t);  if (map != null)        map.set(this, value);  else      createMap(t, value);  }  ThreadLocalMap getMap(Thread t) {  return t.threadLocals;  }   public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; }

For details, let's look at the source code, but one thing is verifiable, that is, the thread copy created in Threadlocal, which can be cleared without calling remove, the jvm will perform automatic garbage collection when it finds that the thread commissioning is no longer in use. I used to write programs to clean up Threadlocal frequently. (Prevent memory usage. If the number of created replicas is not too large, the virtual machine can be automatically cleared)




ThreadLocal usage

As early as Java 1.2 was launched, the Java platform introduced a new support: java. lang. ThreadLocal, which provided us with a new choice when writing multi-threaded programs. With this tool class, you can easily compile a beautiful multi-threaded program. Although ThreadLocal is very useful, it seems that there are not many friends who know it and use it.

What is ThreadLocal?

What is ThreadLocal? In fact, ThreadLocal is not a local implementation version of a Thread, it is not a thread, but Thread local variable (thread local variable ). It may be more appropriate to name it ThreadLocalVar. ThreadLocal is a simple function. It provides a copy of the variable value for every thread that uses the variable. Each thread can change its own copy independently, it does not conflict with copies of other threads. From the thread perspective, it seems that every thread has the variable completely. Thread Local variables are not new in Java. In other language compilers (such as ibm xl fortran), they provide direct support at the language level. Java does not provide direct support at the language level, but provides a ThreadLocal class to support it. Therefore, the code for compiling local variables of threads in Java is relatively clumsy, this may be one of the reasons why local variables of threads are not widely used in Java.

ThreadLocal Design

First, let's look at the ThreadLocal interface:

Object get (); // returns the copy of the local variable of the current thread protected Object initialValue (); // returns the initial value of the current thread of the local variable of this thread
Void set (Object value); // set the value of the local variable copy of the current thread

ThreadLocal has three methods, among which initialValue () is worth noting. This method is a protected method, which is specifically implemented for subclass rewriting. This method returns the initial value of the local variable of the current thread. This method is a delayed call method that is executed only when a thread calls get () or set (Object) for 1st times, and only once. The true implementation in ThreadLocal directly returns a null:

Protected Object initialValue () {return null ;}

How does ThreadLocal maintain copies of variables for each thread? In fact, the implementation idea is very simple. There is a Map in the ThreadLocal class, which is used to store copies of the variables of each thread. For example, the following example is implemented:

Public class ThreadLocal
{
Private Map values = Collections. synchronizedMap (new HashMap ());
Public Object get ()
{
Thread curThread = Thread. currentThread ();
Object o = values. get (curThread );
If (o = null &&! Values. containsKey (curThread ))
{
O = initialValue ();
Values. put (curThread, o );
}
Return o;
}

Public void set (Obj ...... remaining full text>

In multithreading, why must shared variables be modified using final in main ()?

The problem was raised very well. I finally found out the cause. First, I corrected the questioner's question. The first piece of code I posted was an anonymous internal class, and the second-end code was not an anonymous internal class.

To answer your question, why should I add a final modifier to reference an external object in an anonymous internal class, the external objects referenced in the anonymous internal class are restricted by the scope of the External Thread and have a specific life cycle. Taking the thread as an example, when the life cycle of the external variable has been completed, the internal thread is still running. How can we solve the problem that the external life cycle has ended but needs to be used internally? At this time, we need to add the final modifier to the external variable, in fact, the internal Anonymous class uses this variable as a "Replica" of the external variable. Even if the life cycle of the external variable has ended, the internal "Replica" is still available.

The answer to the Web search is as follows:
Why must the anonymous internal class parameter be of the final type?
1) from the theory of programming language: Local internal classes (that is, internal classes defined in methods ), because it is inside the method (which can be displayed at the formal Parameter definition or the method body), accessing local variables (formal parameters or local variables) in the method is justified. is natural
2) Why should I add a limit in JAVA: I can only access Partial Variables of the final type?
3) the compiler designer of the JAVA language is of course fully implemented: the local internal class can access all the local variables in the method (because: theoretically this is a natural requirement),: compilation technology is unfeasible or costly.
4) Where are the difficulties? Where is the problem?
The lifecycle of a local variable is inconsistent with that of an object of a local internal class!
(5) method f is called, and variable I is generated in its call stack. At this time, a local internal Class Object inner_object is generated, which accesses the local variable I. when method f () finishes running, the local variable I is dead and does not exist. however, the local internal Class Object inner_object may still exist (only when no one references this object will it die), and it will not end with method f. in this case, a "Absurd" result is displayed: The inner_object object of the local class needs to access a nonexistent local variable I!
6) How can we achieve this? When the variable is final, a copy of the final local variable is copied, and the copy is directly used as a data member in the local. in this way, when a local internal class accesses a local variable, it actually accesses the "Replica" of this local variable (that is, this replica represents the local variable ). therefore, when the real local variable in the running stack dies, the local internal class object can still access the local variable (actually accessing the "Replica"), giving people the feeling: it seems that the "Life Cycle" of a local variable has been extended.
So the core question is: how can we make the semantic Effect of accessing a "Replica" and accessing a real local variable be the same?
When a variable is final, if it is of the basic data type, its copy is the same as the original volume because its value remains unchanged. the semantics is the same. (if it is not final, it cannot be guaranteed that the replicas are consistent with the original variables, because the original variables are changed in the method, and the replicas are changed in the local internal class)

When a variable is final, if it is of the reference type, its reference value remains unchanged (that is, it always points to the same object). Therefore, its replica is the same as the original reference variable, always point to the same object (because it is final, so that: can only point to this object, and can not point to other objects),: the duplicates accessed in the local internal class and the original objects accessed in the method code are always the same, that is, the semantic effect is the same. otherwise, when the original variables are changed in the method and the replicas in the local internal class are changed, there is no guarantee that the replicas are consistent with the original variables (therefore: they should have been the same variable .)

One sentence: this rule is helpless. note: The design of the programming language is restricted by the implementation technology. this is an example. because: I have seen many people hold this idea ...... remaining full text>

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.