Netty Learning Tour----threadlocal principle analysis and performance optimization thinking (think article)

Source: Internet
Author: User
Tags data structures set set stub thread class
1, java.lang.ThreadLocal overview ThreadLocal, local thread variable, each thread retains a copy of a shared variable. Actually, I'm not quite sure. Each thread holds a copy of the shared variable, but threadlocal is a way of implementing the thread context environment. The database transaction as a common scenario to illustrate, for example, each thread needs to access the database, you need to get the database connection connection object, in practice, we will use the database connection pool to re-use connection, first thread pool, here is a shared variable, The implementation of a thread pool must ensure that multiple threads get connection from the thread pool at the same time, and then each thread uses a separate connection, and the connection is occupied by one thread, and the other threads are not used at all. Nor does it attempt to use a connection object that has been occupied by other threads. Since a thread may need to manipulate the database more than once during execution, our design is that a thread is in the process of dealing with only one connection, that is, the execution process of the entire thread (the execution environment) needs to preserve the newly acquired connection, the simplest and most effective way, is to keep this connection in one of the properties of the thread object, threadlocal is doing it. Threadlocal is not a copy of this connection, multiple threads Use this copy, not so, a connection object at any time, not copied multiple copies. My point of view: Threadlocal is a thread-local variable that is the execution context of a thread.
2, from the threadlocal get method source analysis of its implementation logic
/** * Returns the value in the current thread ' s copy of this * thread-local variable. If the variable has no value for the "* Current thread", it is the I-initialized to the value returned * by a INV
     Ocation of the {@link #initialValue} method. * @return The current thread's value of this thread-local */public T get () {Thread T = thread.cu    Rrentthread ();   @1 Threadlocalmap map = getmap (t);     @2 if (map!= null) {Threadlocalmap.entry E = map.getentry (this);
        @3 if (e!= null) return (T) E.value;                      return Setinitialvalue (); @4} 
Code @1 to get the current thread. Code @2, obtaining Threadlocalmap from current thread, Threadlocalmap getmap (thread t)  {         return t.threadLocals;    &NBSP}, here is the threadlocals variable that returns the thread object directly, it's a little bit interesting, so threadlocal is the local variable of the thread, that's the meaning, the place where the data really resides is the thread object itself, In fact, the next will be more interesting: we entered the threadlocalmap source analysis, learned that the original threadlocalmap is a map structure (K-V) key-value pairs, on the inside of the source code will not be analyzed, threadlocalmap ( Threadlocal firstkey, object firstvalue),firstkey  for ThreadLocal, Magic Bar, In fact, this is why thread's local variable data type is a map prototype, a thread can be associated with multiple threadlocal, each statement one, on the thread of the threadlocals increase to a key value of,key  for the   ThreadLocal, and value is the object of the specific deposit. Code @3, if the thread's threadlocalmap is not empty, return the pair directly, or enter the code @4 code @4, initialize and get the variable put into the threadlocal. The above is threadlocal core design concept, in order to more intuitive description of the threadlocal principle, examples:
-----------------------------------------------------------------------public class ThreadLocalDemo1 {private

    Static final threadlocal<string> schemalocal = new threadlocal<string> ();

        public void Test1 () {String a = Schemalocal.get ();
        ThreadLocalDemo2 Demo2 = new ThreadLocalDemo2 ();
    Demo2.test (a); public static void Main (string[] args) {//TODO auto-generated ' method stub}} ' public class Threadl

    OcalDemo2 {private static final threadlocal<string> slocal = new threadlocal<string> ();
        public void Test (string b) {String a = Slocal.get ();
    Other code System.out.println (b);  public static void Main (string[] args) {//TODO auto-generated ' method stub}} ' public class Testmain {public static void main (string[] args) {//TODO auto-generated method stub ThreadLocalDemo1 d =
        New ThreadLocalDemo1 ();

    D.test1 ();
}
} 
A thread invokes the  ThreadLocalDemo1   test1 method, which involves two threadlocal variables in this execution chain, calls the Threadlocal get method, first obtains the current thread, Then get the thread internal properties from the current thread object [Threadlocal.threadlocalmap threadlocals = null;], Then, from the Threadlocalmap, take the Threadlocal object as the key and get the stored value from the Threadlocals map. The thread's Threadlocals value is {     ThreadLocalDemo1.schemaLocal  :  The value in the variable,       ThreadLocalDemo2.scloal :  values stored in this thread   &nbsp---------------------- --------------------------------------------------------------3,  threadlocal optimization thinking      The Threadlocal data access algorithm is essentially the access feature of map.   I in the analysis of HashMap source code, has been explained HASHMAP storage structure, if interested, you can browse my blog: Deep Understanding hashmap:http://blog.csdn.net/prestigeding/ Article/details/52861420,hashmap according to Key's access speed efficiency is very fast, why. Because HashMap according to the hash of key, then will be positioned to the internal data slot (the data is an array structure), as we all know, according to the array of subscript access, access speed is the fastest, that is, hashmap based on key positioning faster than LinkedList, etc. Next to the array access mode, this is because the HashMap is more than one step in the hash location slot (of course, if there is a hash conflict that is more slow). Therefore, if you need to further optimize the threadlocal access performance in a high concurrency scenario, it is necessary to get from the thread object (THReadlocals  data structure, if the data structure can be modified to an array, and then each Threadlocal object to maintain its subscript that is perfect. Yes, the Netty framework is for high concurrency, because the number of concurrent access, a little bit of performance optimization, will bring considerable performance improvement effect, Netty mainly from the following two aspects of the implementation of the threadlocal to optimize 1) thread objects directly provide  set, Get method so that the thread-local storage-related variable properties are directly obtained. 2 data storage is based on array storage.
4, Netty on the optimization of the threadlocal mechanism because threadlocal is the JDK to achieve the original, the universality is very strong, direct expansion of customization is not a wise choice, so netty in the optimization of the threadlocal of the way is the other stove, Implement the semantics of threadlocal. The optimization method is as follows: 1 provides an interface, fastthreadlocalaccess, and is customized to the thread pool factory class, The created thread inherits the Java.lang.Thread class and implements the Fastthreadlocalaccess interface, providing a direct setting to get the method of the thread-local variable. 2 provides the Fastthreadlocal class, which implements the same semantics as threadlocal. 3 provides the Internalthreadlocalmap class, which is similar to the Java.lang.ThreadLocal.ThreadLocalMap class, and is used for threads to store real data structures. 4.1 Extended Thread object, provides Set,get method through the custom thread pool factory, created threads object is the extended thread object, in Netty corresponds to Fastthreadlocalthread, the class itself is very simple, worthy of attention is its idea,      The thread pooling implementation mechanism provided in the JDK and contract provides the extension point of the factory created by the thread, and here is the typical practice. Here is attached its source code, do not read:
public class Fastthreadlocalthread extends Thread implements fastthreadlocalaccess {private Internalthreadlocalmap t

    Hreadlocalmap;
    Public Fastthreadlocalthread () {} public fastthreadlocalthread (Runnable target) {super (target);
    Public Fastthreadlocalthread (Threadgroup Group, Runnable target) {super (group, target);
    Public Fastthreadlocalthread (String name) {super (name);
    Public Fastthreadlocalthread (Threadgroup Group, String name) {super (group, name);
    Public Fastthreadlocalthread (Runnable target, String name) {super (target, name); 
    Public Fastthreadlocalthread (Threadgroup Group, Runnable Target, String name) {Super (group, target, name); Public Fastthreadlocalthread (Threadgroup Group, Runnable Target, String name, long stacksize) {super (
    Group, target, name, stacksize); }/** * Returns The internal data structure that keeps the thread-local variables bound to this thread.
     * This is the ' is ' for internal-only, and thus are subject to-change in any time.
    * * @Override Public final Internalthreadlocalmap Threadlocalmap () {return threadlocalmap;
     }/** * Sets The internal data structure that keeps the thread-local variables to this thread.
     * This is the ' is ' for internal-only, and thus are subject to-change in any time. * * @Override public final void Setthreadlocalmap (Internalthreadlocalmap threadlocalmap) {this.threadlocal
    Map = Threadlocalmap; }
}
4.2 Fastthreadlocal and Internalthreadlocalmap internalthreadlocalmap are data structures where threads store local variables, each thread has its own internalthreadlocalmap, Its function is the same as Java.lang.ThreadLocal.ThreadLocalMap inner class, and fastthreadlocal, its semantics and ThreadLocal, outward performance and ThreadLocal same. Again, Netty's internalthreadlocalmap is an array of internal numbers. Thread-local variables, to see from the point of view of the thread's execution flow, a thread passes through multiple classes during execution, and there are multiple classes in which the thread local variables are declared (refer to the example described above in threadlocal), so the array here is to keep threads throughout the execution of the thread, Different ThreadLocal variables hold different data, the implementation of Java.lang.ThreadLocal.ThreadLocalMap inner class uses the map structure, the key is ThreadLocal object, and the value is the value of the true saved variable. Internalthreadlocalmap since it is an array, the array is one-dimensional, the array will eventually only save the value of the variable that really want to keep, then how to distinguish the different threadlocal in the internalthreadlocalmap subscript it. The way Netty is to keep the subscript in fastthreadlocal, we know, is to use local thread variables, fastthreadlocal declarations, typically class variables (static variables), such as: private static final ThreadLocal athreadlocal = new ThreadLocal (); The number of ThreadLocal in the system is not much, The subscript (offset) of each fastthreadlocal in the Internalthreadlocalmap is determined at fastthreadlocal load time and remains unchanged. And the first element of each internalthreadlocal internal array, which holds the Fastthreadlocal object in the system running. Internalthreadlocalmap's internal data structure is:/** used by {@link  fastthreadlocal} */Object[]  IndExedvariables; Now to illustrate the above theory, such as the whole project, there are a,b,c,d,e5 classes in each declared a static fastthreadlocal variable, class loading order for   A, B  , D, E, C, the fastthreadlocal storage of class A The internalthreadlocalmap of the thread variable is 1,b, the 2,d is 3, and then the inner push, such as the thread T1, in the process of one request, the A,e,c in the three classes that need to be used, then threads Fastthreadlocalmap, In the Internalthreadlocalmap Reservoir, the subscript 1 is a, the 2,3 element is empty, subscript 4 is E, subscript 5 holds the variable value in C. Each thread internalthreadlocalmap subscript 0 is a set set that holds valid fastthreadlocal variables in the system's operation. Based on such storage, the Fastthreadlocal Get,set method is stored directly in the Internalthreadlocalmap array according to the subscript, of course, It is worth mentioning that the length of the array element in Internalthreadlocalmap defaults to 32, if the number of fastthreadlocal of the system more than 32, will multiply the expansion. Fastthreadlocal study of the entrance, suggested from the Set,get method to start, know the above principle, the source of reading should be easier, do not do too much explaining.     If you are willing to share technical experience, welcome Gathen: Internet Technology Group 34265357

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.