This article is mainly organized by Lu Zhou, "Struts2 technical insider"
Design pattern: it is a summary of a set of code Design experience formed after repeated practices by programmers.
ThreadLocal mode: a solution to solve the Data Sharing Problem in multi-threaded programs.
1. thread security issues
In traditional Web development, the most common way to process Http requests is to implement Servlet objects to respond to Http requests. Servlet is one of the most important J2EE standards and defines how Java responds to Http requests. With the HttpServletRequest and HttpServletResponse objects, we can easily interact with Web containers.
When a Web Container receives an Http request, a main scheduling thread in the Web Container allocates a current working thread to the defined thread and distributes the request to the current working thread, this thread executes the service method in the corresponding Servlet object. When the worker thread is executing, the Web Container receives another request. The master scheduling thread selects another worker thread from the thread pool to serve the new request. The Web container does not care whether the new request accesses the same Servlet instance. Therefore, we can draw a conclusion:For multiple requests of the same Servlet object, the Servlet service method will be concurrently executed in a multi-threaded environment.Therefore, Web containers useMultiple Threads for a single instance (single Servlet instance)To process Http requests. This processing methodThis reduces the cost of creating a Servlet instance and shortens the response time to Http requests.However, such a processing method may cause thread security issues for variable access. That is to say, the Servlet object is not a thread-safe object.
To address the issue of length and respect for zwchen's original works, the Servlet object is not a test instance of a thread-safe object. I wrote an article separately:
Servlet thread security
If you want to know this article well, you 'd better read it!
Concepts related to thread security
Speaking of thread security, it is easy to confuse many beginners in terms of concept. Thread security means that in a multi-threaded environment, when a class executes a method, it is safe to access the internal instance variables of the class. Therefore, there is no thread security statement for the two types of variables listed below:
1) Any parameter variables in the method signature.
2) local variables in the method.
Any access to variables in the above form is thread-safe, because they are in the internal method and managed by the current execution thread.
This is the origin of thread security issues:In the traditional Servlet-based development mode, the instance variables inside the Servlet object are NOT thread-safe.In a multi-threaded environment, access to these variables must be controlled by special means.
There are many ways to solve thread-safe access, and Synchronized is an easy way to come up with. However, for the sake of Web application efficiency, the feasibility of this mechanism in Web development is very low, and it violates the original design intention of Servlet. Therefore, we need to find another way to solve this problem.
Implementation Mechanism of ThreadLocal Mode
In earlier versions of JDK, a solution is provided to solve the problem of multi-thread concurrency: java. lang. ThreadLocal class. When maintaining variables, the ThreadLocal class actually uses an independent copy of ThreadLocalMap in the current Thread. Each Thread can independently modify its own copy without affecting each other, this isolates threads and threads to avoid conflicts between variables accessed by threads.
ThreadLocal is not a thread, but is isolated from other threads by operating an internal variable in the current thread. ThreadLocal indicates that the operation object is a local variable of the thread. If we look at the source code implementation of Thread, we will find this variable, as shown below:
Thread. java>
1 public class Thread implements Runnable {2 // many other codes are omitted here. 3 ThreadLocal. ThreadLocalMap threadLocals = null; 4}
ThreadLocalMap is defined in the ThreadLocal class, but the real reference is in the Thread class.
This is part of the Thread source code in JDK. We can see that ThreadLocalMap exists along with the current Thread. Different Thread threads have different ThreadLocalMap local instance variables, which is also the meaning of "copy. Next, let's take a look at how ThreadLocal. ThreadLocalMap is defined and how ThreadLocal operates it. As follows:
ThreadLocal. java>
1 public class ThreadLocal <T> {2 // many codes are omitted here. 3 4 // Save the value to the local variable of the current thread. 5 public void set (T value) {6 // get the current Thread 7 Thread t = Thread. currentThread (); 8 // call the getMap method to obtain the local variable ThreadLocalMap 9 ThreadLocalMap map = getMap (t) in the current thread; 10 // If TheadLocalMap already exists, use 11 if (map! = Null) 12 // The current ThreadLocal instance is the key and stored in TheadLocalMap of the current thread. 13 // if the current thread defines multiple different ThreadLocal instances, they store data as different keys without interfering with each other. set (this, value); 16 else17 // If TheadLocalMap does not exist, a new 18 createMap (t, value) is created for the moment ); 19} 20 // get the variable value 21 public T get () {22 // get the current Thread 23 Thread t = Thread. currentThread (); 24 // obtain ThreadLocalMap25 ThreadLocalMap map = getMap (t) in the current thread; 26 if (map! = Null) {27 // get the variable value of the current thread whose current ThreadLocal instance is key 28 ThreadLocalMap. Entry e = map. getEntry (this); 29 if (e! = Null) 30 return (T) e. value; 31} 32 // when map does not exist, set the initial value 33 return setInitialValue (); 34} 35 private T setInitialValue () {36 T value = initialValue (); 37 Thread t = Thread. currentThread (); 38 ThreadLocalMap map = getMap (t); 39 if (map! = Null) 40 map. set (this, value); 41 else42 createMap (t, value); 43 return value; 44} 45 // get TheadLocalMap 46 ThreadLocalMap getMap (Thread t) {47 return t in the current Thread. threadLocals; 48} 49 // create ThreadLocalMap50 void createMap (Thread t, T firstValue) {51 // call the constructor to generate TheadLocalMap52 t in the current Thread. threadLocals = new ThreadLocalMap (this, firstValue); 53} 54 // ThreadLocalMap definition 55 static class ThreadLocalMap {56 // a lot of code is omitted here 57} 58}
From the code above, we can see the general structure of the ThreadLocal class and the ThreadLocalMap operation. We can draw the following conclusions:
The ThreadLocalMap variable belongs to the internal attributes of the thread (which is thread-safe). Different threads have completely different ThreadLocalMap variables.
The value of the ThradLocalMap variable in the thread is created when the ThreadLocal object performs the set or get operation.
Before creating ThradLocalMap, the system first checks whether the ThradLocalMap variable in the current thread already exists. If not, it creates one. If yes, it uses the ThradLocalMap created by the current thread.
The key to using ThradLocalMap of the current thread is to use the current ThradLocal instance as the key for storage.
The ThradLocal mode achieves Data Access isolation in at least two aspects: horizontal isolation and vertical isolation. With two different isolation modes, horizontal and vertical, ThradLocal can truly achieve thread security.
Vertical isolation---- Data Access isolation between threads. This is ensured by the data structure of the thread. Because every thread accesses ThradLocalMap of each thread during object access.
Horizontal isolation---- Objects operated by different ThradLocal instances in the same thread are isolated from each other. This is ensured by ThradLocalMap using the current ThradLocal instance as the key during storage.
In-depth comparison of TheadLocal mode and synchronized keywords
The keywords of ThreadLocal mode synchronized are used to deal with the problem of multi-thread concurrent access variables, but they have different perspectives and ideas for solving the problem.
1) ThreadLocal is a java class. Through operations on local variables in the current thread, the variable access conflict between different threads is solved. Therefore, ThreadLocal provides a thread-safe shared object mechanism, with each thread having its copy.
2) synchronized in Java is a reserved word. It relies on the JVM locking mechanism to implement atomicity of functions or variables in the critical section. In the synchronization mechanism, the object lock mechanism ensures that only one thread accesses the variable at a time. At this time, multiple threads share the variable used as the "Lock Mechanism.
The synchronization mechanism (the synchronized keyword) uses the "time-for-space" method to provide a variable for different threads to queue for access. ThreadLocal uses the space-for-time method to provide a copy of the variable for each thread, so as to achieve simultaneous access without affecting each other.
Not finished! To be continued !!!
Design Pattern in Struts2 ---- ThreadLocal pattern continuation