当前位置:网站首页>Hot knowledge of multithreading (I): introduction to ThreadLocal and underlying principles

Hot knowledge of multithreading (I): introduction to ThreadLocal and underlying principles

2022-07-05 02:47:00 It was his highness xiaoaojun

ThreadLocal brief introduction

So first of all , We need to know what is ThreadLocal Well ? The following are the official documents ThreadLocal Brief introduction :

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; after a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

This class provides thread local variables , These variables are different from ordinary variables , Because every thread that accesses these variables ( adopt get or set Method ) All have their own 、 Independently initialized variable copies .ThreadLocal Instances usually want to associate private static fields in a class with threads ( for example , user ID Or business ID) The associated .

As long as the thread is active and ThreadLocal Instance can access , Each thread holds an implicit reference to a copy of its thread local variable ; After the thread disappears , All copies of their thread local instances will be garbage collected ( Unless there are other references to these copies ).

In popular words, it is ,ThreadLocal A separate copy of the variable is saved for each thread , In this way, different threads only need to operate on their own variables . Thus, complex steps such as synchronization are avoided .( Very arrogant thought , As long as every thread has variables , Don't you have to synchronize those complex operations ?!

 Insert picture description here

Understand the finished ThreadLocal What is it , Under what circumstances is it suitable to use ThreadLocal Development ?

be based on ThreadLocal Its own characteristics , It is mainly applicable to modifying variables under some multithreads , But we don't want the variables to affect each other .
The most typical usage , It is used for Save the request header information of the front-end request .

Because usually , Every time the front-end request server will start a new thread for processing and transmission , Then in the request header Header information , It must only belong to this thread , Based on this point , It's easy to be with Thread Local It is combined with the feature of thread isolation .

 Insert picture description here

In this case , It can ensure that each thread will get the request header information of its corresponding front-end request . Of course, there are other scenes , For example, how to distinguish whether the current request is a pressure measurement request or a normal request during pressure measurement , Both can be used ThreadLocal To implement .

ThreadLocal Principle analysis

that ,ThreadLocal How does the bottom layer implement such a structure to support its unique variables for each thread ? Next, let me show you how the underlying source code is implemented .

get Method

First let's look at get Method , The source code is as follows :

public T get() {
    
  Thread t = Thread.currentThread(); //  Get the current thread 
  ThreadLocalMap map = getMap(t); //  Get the corresponding thread ThreadLocalMap
  if (map != null) {
    
    ThreadLocalMap.Entry e = map.getEntry(this); //  From this map Get the corresponding Entry structure 
    if (e != null) {
    
      @SuppressWarnings("unchecked")
      T result = (T)e.value; //  Generic Programming , Convert to the corresponding required type .
      return result;
    }
  }
  return setInitialValue();
}

You can see , The key point is ThreadLocalMap And the corresponding Entry structure . So what are these two things ?

static class ThreadLocalMap {
    
  static class Entry extends WeakReference<ThreadLocal<?>> {
    
    Object value;
    Entry(ThreadLocal<?> k, Object v) {
    
      super(k);
      // value  The corresponding is actually Thread In the ThreadLocal The next value .
      value = v; 
    }
  }
 	...... 
    
  private Entry[] table; 
  
	......

You can see , actually ThreadLocalMap It's just one. Entry Array . And each Entry The corresponding thread is in a ThreadLocal The next value . The reason for this design is to give full consideration to the possible existence of multiple threads ThreadLocal The situation of . The specific diagram is as follows :

image-20220213133707648

So that way , We can sort it out from ThreadLocal Get the logic of the value :

1、 Get the current thread Thread

2、 according to Thread Get the corresponding ThreadLocalMap

3、 from ThreadLocalMap Get the current ThreadLocal Corresponding Entry, And back to Entry The value in the .

Memory leak

One small detail that needs attention is ,ThreadLocalMap Medium Entry Objects are weak references . This may lead to a serious problem , produce Memory leak . Why is there a memory leak ? I'll borrow one here first Threadlocal General illustrations cited :

 Insert picture description here

It can be seen that if the outside world is right at this time ThreadLocal The reference to is cancelled , So at this time ThreadLocal Because it's a weak quote , Will be GC To recycle , thus , We can no longer get the corresponding value The value of , This causes a memory leak .

 Insert picture description here
So why use weak references ? Whether changing to strong reference can solve the problem ?

hypothesis ThreadLocal Strong references are used , So when you're right ThreadLocal After the reference of is cancelled ,ThreadLocal Because it is still ThreadLocalMap Points to , Therefore, it is impossible to recycle . The details are shown in the following figure :

 Insert picture description here

Then it will still cause the problem of memory leakage , Even more “ many ”.

So obviously, essentially , Weak references are not the cause of memory leaks . actually , To avoid memory leaks , We still need our thread to take the initiative " Cut off the " quote . That is, after each use , Call the corresponding remove Method to clear .

 Insert picture description here

set Method

Look again set Method , In fact, the logic is similar . I put the source code here first :

public void set(T value) {
    
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}

You can see the overall process as follows :

1、 First, get the current thread Thread.

2、 Get map Corresponding ThreadLocalMap object .

3、 Judge the present ThreadLocalMap Has it been created , If it has been created, insert the value (key yes ThreadLocal,value It's us set Value ).

4、 Otherwise, proceed map The initialization .

ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
    
    table = new Entry[INITIAL_CAPACITY]; //  Initialize array , Length default 16
    int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); //  Calculate the corresponding hash subscript 
    table[i] = new Entry(firstKey, firstValue);
    size = 1;
    setThreshold(INITIAL_CAPACITY); //  Set the expansion threshold 
}

I also put the key code of initialization here ~ If you can understand the above knowledge almost , Then the initialization here must be no problem ~.

ThreadLocal Analysis of advantages and disadvantages

advantage

1、 For common locking to ensure mutual exclusion, solve the problem of multi-threaded access ,ThreadLocal Put forward new ideas , Use the method of assigning variables to each thread to solve the conflict . The performance is relatively good .

2、 The modification of variable data by each thread is independent , No interaction .

shortcoming

1、 Pay attention to calling after use remove Method to clear the corresponding reference , Avoid memory leaks .

2、 because ThreadLocal The mechanism of action is bound to threads , therefore It cannot be directly used to save the data of asynchronous tasks , It needs to be operated in some other way . About how to realize , Please look forward to my subsequent articles hahaha ~

If you see this , Give me a compliment 、 Click a collection , If only I could pay attention ~

It's not easy to create , Thank you for your support ~

reference

When are weak references recycled _ interviewer :ThreadLocal Why memory leaks occur ?

原网站

版权声明
本文为[It was his highness xiaoaojun]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140856502396.html