A question that afflicts many people

Reading this article requires a general understanding of ThreadLocal. Let’s cut to the chase.

【Java】【 source 】

1. Ask

Serial four:

  • How does ThreadLocal work?
  • The cause of the memory leak?
  • Is InheritableThreadLocal used?
  • What is Netty’s FastThreadLocal?

2. The analysis

ThreadLocal is often used as the primary programming tool for implementing “thread closure”. For example, for example, traditional SimpleDateFormat is not thread-safe. If you declare it as a global variable, it will cause time distortion in a concurrent environment. A good solution is to use ThreadLocal.

ThreadLocal is widely used. Spring’s transaction management, for example, is implemented through it. However, it does have a weak point: it can’t pass through (it can’t be accessed by quilt threads), so InheritableThreadLocal and even more advanced wrapped libraries are created.

3. A

3.1 How does ThreadLocal work?

Read the source code is not difficult to answer. The get and remove methods of ThreadLocal are just a shortcut to use. Its real data resides in a thread structure called ThreadLocalMap.

The value of a ThreadLocal is distributed among N threads, depending on the thread. So there are two steps to getting the Value of a ThreadLocal.

  • The first step is to get the Map by thread
  • The second one gets the value from the Map by itself, so its this is the Map Key

It doesn’t make any sense. This is a data structure designed to accommodate coding conventions.

3.2 Causes of Memory Leaks?

Strictly speaking, ThreadLocal has no memory leak problem. If so, you forgot to perform the remove method. This is caused by incorrect use.

This is consistent with other memory leak problems, such as:

  • Stream not closed
  • The connection is not broken
  • Abuse of the static map

Why is there a leak problem?

If you don’t call remove, the value of ThreadLocal will remain in place until the current thread is destroyed.

It is well known that threads have long lifetimes, and the common use of thread pools makes them even longer. If you don’t remove it, of course you won’t release it. It doesn’t really matter whether Key is a weak reference or not.

In that case, whether it is a leakage problem is a matter of wording. The interview process is a discussion, not necessarily a standard answer.

Data corruption caused by thread pools is more of a concern than memory leaks. Since the data placed in ThreadLocal will not be very large, the leak will only take up a bit of memory. And data confusion, but will cause business bugs.

3.3 Is InheritableThreadLocal used?

InheritableThreadLocal is used when InheritableThreadLocal is passed between parent and child threads, eliminating the problem that threadLocal can’t pass values between parent and child threads.

This is essentially done through Thread. Properties are copied using two maps.

/* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
Copy the code

Don’t get too excited. In the case of thread pools, threads are cached and used over and over again. The context passing of the parent-child thread relationship is meaningless.

Additional question: how did you solve it?

Ali has a library here, github.com/alibaba/tra… Specifically addressing variable sharing across threads. If you’re meeting Ali, you might as well lick it.

3.4 What is Netty’s FastThreadLocal

Since Java already has ThreadLocal classes, why did Netty create its own structure called FastThreadLocal?

Let’s first look at the implementation of ThreadLocal.

The Thread class has a member variable, threadLocals, which holds all the custom information related to the Thread. The definition of this variable is in the Thread class, and the operation is in the ThreadLocal class.

The problem is that the ThreadLocalMap class, although called Map, has no interface to implement Map. Instead of using HashMap’s array + list + red-black tree approach to rehash, ThreadLocalMap uses only one array, and uses open addressing (searching until it reaches an empty location in case of collisions), which is very inefficient.

Because Netty uses ThreadLocal so much, it has been specifically optimized. It is fast because it works on the underlying data structure, using constant subscripts to locate elements rather than using the JDK’s default probing algorithm.

The underlying InternalThreadLocalMap optimizes the cacheline accordingly.

Welcome to pay attention to my B station account

B station account

If the content helps you, welcome everyone to like, favorites + attention

Learning exchange group

Communication group