instructions

Interviewer: Tell me what you understand about ThreadLocal.

So what should we answer ???? You can also think about it, let’s think about it at zero;

  • What is ThreadLocal used for?

  • ThreadLocal some details!

  • Best practices for ThreadLocal!

  • thinking

What is ThreadLocal used for?

Before we discuss what ThreadLocal can be used for, let’s be clear: if there is only one thread, then we don’t even need to talk about ThreadLocal, ThreadLocal is used for multi-threaded scenarios!!

ThreadLocal boils down to two types of uses:

  • Save thread context information, available wherever needed!!
  • Thread-safe, avoid the performance penalty of thread-safe synchronization in some cases!!

Save thread context information, available wherever needed!!

Due to the nature of ThreadLocal, the same thread can be set in one place and then retrieved anywhere. This can be used to store thread context information.

ThreadLocal can be used to set a request to any method that needs to be logged to get the request ID and string the request together.

For example, Spring’s transaction management uses ThreadLocal to store connections, so that each DAO can obtain the same Connection and carry out transaction rollback, commit and other operations.

Note: The use of ThreadLocal is often used in excellent frameworks, but we rarely use ThreadLocal in the following scenarios.

Thread-safe, avoid the performance penalty of thread-safe synchronization in some cases!!

ThreadLocal provides a new way to solve the concurrency problem of multithreaded programs. But ThreadLocal has its limitations, so let’s take a look at the Ali specification:

Each thread reading or writing data to or from a ThreadLocal is thread isolated and does not affect each other, so ThreadLocal cannot solve the problem of updating shared objects!

Since there is no need to share information, there is no race problem, which ensures thread safety in some cases and avoids the performance penalty of having to synchronize when thread safety is considered!!

This kind of scenario is also mentioned in ali specification:

ThreadLocal some details!

Sample code for ThreaLocal use:

public class ThreadLocalTest {
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {

        new Thread(() -> {
            try {
                for (int i = 0; i < 100; i++) {
                    threadLocal.set(i);
                    System.out.println(Thread.currentThread().getName() + "= = = ="+ threadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } finally { threadLocal.remove(); }},"threadLocal1").start();


        new Thread(() -> {
            try {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName() + "= = = ="+ threadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } finally { threadLocal.remove(); }},"threadLocal2").start(); }}Copy the code

Code screenshot:

Code running results:

From the result of the run, we can see that threadLocal1 does not have any effect on threadLocal2.

Overview of Thread, ThreadLocalMap, and ThreadLocal

Thread class have threadLocals attribute variables (type is ThreadLocal ThreadLocalMap), that is to say, each Thread has an own ThreadLocalMap, so each Thread to isolate the ThreadLocal, speaking, reading and writing, And they don’t affect each other.

A ThreadLocal can only store one Object. If you need to store multiple Object objects, you need to store multiple ThreadLocal objects!!

As shown in figure:

The Entry key points to a ThreadLocal and dotted lines indicate weak references. Let’s look at ThreadLocalMap:

References to Java objects include: strong references, soft references, weak references, and virtual references.

Because weak references are involved here, a quick note:

Weak references are also used to describe non-essential objects, and when the JVM does garbage collection, the object is only associated with weak references and is collected, regardless of whether memory is sufficient.

ThreadLocal will be retracted when only the key of an Entry in a ThreadLocalMap points to a ThreadLocal.

After a ThreadLocal is garbage collected, the key value of the corresponding Entry in the ThreadLocalMap will become null, but the Entry is a strong reference, so the Object stored in the Entry cannot be collected. So ThreadLocalMap does some extra collection.

There is also a risk of memory leaks (I have not encountered many similar scenarios on the web, so I will mention ThreadLocal best practices below!!).

Best practices for ThreadLocal!

After a ThreadLocal is garbage collected, the key value of the corresponding Entry in the ThreadLocalMap will become null, but the Entry is a strong reference, so the Object stored in the Entry cannot be collected. So ThreadLocalMap does some extra collection.

Note: most of the time, we are used in the thread pool scenario, the application does not stop, the thread will not destroy!!

Because of the long life cycle of threads, if we set a large Object into a ThreadLocal, the set, get, and other methods will be called for additional cleanup under certain conditions, but after the ThreadLocal is garbage collected, The key value of the corresponding Entry in ThreadLocalMap will be null, but there will be no further operations on set, get, etc.

Therefore, as a best practice, we should actively call the remove method to clean up when we are not using it.

If a ThreadLocal is static, the key to an Entry in a ThreadLocalMap will always be there. If a ThreadLocal is static, the key to an Entry in a ThreadLocalMap will always be there. If a ThreadLocalMap is static, the key to an Entry will always be there.

Best practices should be:

Try {// other business logic} finally {threadLocal object. Remove (); }Copy the code

thinking

If the interview, can be the above content can be said, I think it is very good, the answer is quite perfect. But it would be perfect if you could answer the following.

For ThreadLocal, I read about FastThreadLocal and XXXXX in Netty source code, which is an upgrade.

In my local tests, FastThreadLocal throughput was about 3 times higher than jdkThreadLocal.

Note: Since FastThreadLocal content is also very, very much, and there are many skills, so I will open a special post to string together!!


If you feel that you have gained something after reading it, please click “like”, “follow” and add the official account “Ingenuity Zero” to check out more wonderful history!!