One night, WHEN I was writing code, I needed to use a structure, the function of this structure is very simple, it follows the thread, for different threads, it is natural isolation, I thought about it for a long time, until I entered the dream.

An interesting thing happened in the dream, coola pickup met a new assessment in the full-time hunter, need to teach themselves programming

So Kula Pika visualizes Thread with the ability to visualize

A conversation between man and thread takes place.

Handsome Rice rice: Are you Thread himself?

Thread: Yeah, I was visualized by my coola pickup abilities. Now I can jump and rap.

Handsome rice rice: I wipe, I must be a dream, hurriedly ask this attack street question, while the dream did not wake up, the schedule to solve. Well, I came across a need for a structure, and the function of this structure is very simple, it follows the thread, for different threads, it is naturally isolated, thinking for a long time, still can’t find the answer, you know?

Thread: Yeah, it’s easy, you spicy chicken. Can use ThreadLocal ah, he is a local thread copy variable tools, mainly used for private thread and that thread will deposit a copy of the object to do a map, each thread mutual interference between the variables, in high concurrency scenarios, can realize stateless invocation, suitable for individual threads do not share the operation of a variable’s value, natural separation ability.

Handsome Fan Fan: Yes, yes, it’s ThreadLocal. It meets my needs. What’s the principle?

Thread: ThreadLocal Thread: ThreadLocal Thread: ThreadLocal Thread: ThreadLocal Thread: ThreadLocal Thread: ThreadLocal Thread You know what? I’ll tell you what. Listen up

Each thread maintains a ThreadLocalMap, which is a Map (key,value) data format. The key is a weak reference, which is the ThreadLocal itself, and the value holds the value of the thread variable.

That is, ThreadLocal itself does not store the values of variables in a thread; it is a tool that maintains a Map within the thread to help store and fetch variables.

Data structure, you can look at:

Handsome Fan Fan: I see, I see, there is a Map structure inside, then how to resolve hash conflict?

Thread: That beats me. Hang on, I called ThreadLocal, who has also been embodied by Coola pica.

Oh, oh, oh, I got it.

Unlike HashMap, the ThreadLocalMap structure is very simple and has no next reference, which means that the resolution of Hash conflicts in ThreadLocalMap is not a list but a linear probe. The so-called linear detection is to determine the position of the element in the table array according to the hashcode value of the initial key. If it is found that this position has been occupied by other key values, the fixed algorithm is used to find the next position of a certain step length and judge successively until the position that can be stored is found.

The source code implementation is as follows:

/
 * Increment i modulo len.
 */
private static int nextIndex(int i, int len) {
    return ((i + 1 < len) ? i + 1 : 0);
}

/
 * Decrement i modulo len.
 */
private static int prevIndex(int i, int len) {
    return ((i - 1> =0)? i -1 : len - 1);
}
Copy the code

Handsome Rice Rice: Oh, I see, you just said Key is weak quote? Why is it designed that way?

Therad: I just asked ThreadLocal, and here’s the thing

Why to design in this way, so divided into two cases to discuss:

  • Key uses strong references: This leads to a problem where the object referenced by ThreadLocal is reclaimed, but ThreadLocalMap also holds a strong reference to ThreadLocal, which will not be reclaimed if it is not manually removed, resulting in a memory leak.
  • Key uses weak references: In this case, the referenced ThreadLocal object is reclaimed, and since ThreadLocalMap holds a weak reference to ThreadLocal, the ThreadLocal is reclaimed even without manual deletion. The value is cleared the next time ThreadLocalMap calls set, get, and remove.

Comparing the above two cases, we can find that: The lifetime of a ThreadLocalMap is the same as that of a Thread, so if you do not manually delete the corresponding key, you will cause a memory leak. The optimal solution is that the corresponding value is cleared the next time ThreadLocalMap calls set, GET, and remove.

Handsome Rice: Yeah, I see. Are there any caveats to using ThreadPool?

Thread: Yes, try to avoid memory leaks

Handsome Rice rice: What? Why the memory leak

Thread: Are you stupid?

ThreadLocal is referred to as a weak reference by the Key in the Entry in the ThreadLocalMap, so if a ThreadLocal has no external strong reference to reference it, then the ThreadLocal will be collected in the next JVM garbage collection. The key in the Entry is already collected, but the value is a strong reference that is not collected by the garbage collector, so if the ThreadLocal thread keeps running, the value will never be collected, resulting in a memory leak.

Handsome Rice rice: (⊙ O ⊙)… Terrible. How can that be avoided?

Thread: I don’t know how to solve such a simple problem. Well, the solution is……

Why, suddenly the old mother’s old hen woke me up……