Wechat official account: Rhubarb Run follow me for more interesting interview questions.

Written in the book before

Today we continue with the fifth installment of our Offer to Bowl series — a question that prompts a series of reflections on ThreadLocal.

Why the sudden desire to write an article on ThreadLocal? Recently, there are a lot of new students in the group, who do not understand the application of ThreadLocal in the project, so there are a lot of people asking questions. Therefore, I use my daily time to sort out the core source code of ThreadLocal, which is convenient for myself to understand, and to share with everyone for common communication.

Relatively few people know how ThreadLocal works, and many people probably don’t know much about how to use it because of the limited use scenarios. So ThreadLocal will also be divided into two topics, interviews and source code.

As usual, let’s take a look at how ThreadLocal is examined in an interview.

Common interview questions from ThreadLocal

  1. What is a ThreadLocal? “Why?ThreadLocal?” .ThreadLocalWhat problem does it solve?
  2. ThreadLocalHow bytedance works
  3. ThreadLocalWhen will it be initialized?
  4. ThreadLocalUnderlying structure [Meituan]
  5. threadlocalUnderlying principles, how do I deal with thathashConflicting [Baidu]
  6. ThreadLocalHow to use,ThreadLocalWill produceMemory leaks[Tencent]
  7. What does threadLocal implement, how it works, and what does the business do?
  8. theThreadLocalDo I need to lock it?
  9. Daily workThreadLocalThe scene of

    ……

You can see that ThreadLocal can be asked a lot of questions, but the main categories are: what ThreadLocal is, what it does, the underlying principle, the underlying data structure, the initialization process, the cause of the memory leak… .

Interview scenario Simulation

Ring, ring, ring… A familiar phone rings, opposite came the voice of vicissitudes of life, a listen is just stay up to solve the bug of the eldest brother.

Interviewer: Rhubarb, please introduce yourself first

Rhubarb: Hello, interviewer, my name is Rhubarb…

Interviewer: Have you used ThreadLocal in your daily work? Can you talk a little bit about what ThreadLocal does?

Rhubarb: We know a little bit about this before, ThreadLocal is used to provide thread-local variables. These variables differ from normal variables in that they address thread-dimension variable definitions, with each thread accessing a independently initialized copy of the variable (via its get(), set(), or remove())).

Rhubarb little reminder

ThreadLocal is not designed to solve multithreading problems because variables are in their own threads, so there is no sharing of variables and therefore no contention, so it is inherently thread-safe.

Interviewer: Have you ever looked at the underlying implementation of ThreadLocal?

Rhubarb: The underlying Jdk internal class defines the ThreadLocalMap of the Hash map, which is used to store thread-local variables. ThreadLocalMap itself is a hash Map, in which the key is the thread Id, the value is the Entry value, and the underlying data structure is also an array with an initial size of 16. The value of ThreadLocalMap is an internally defined static internal class Entry, which inherits From WeakReference

Why should rhubarb small reminder Entry inherit from WeakReference?

  • To help deal with the large number and longevity of reference objects, its inner classEntryInheritance inWeakReference, mainly for garbage recycling.

WeakReference functions: when using WeakReference, the garbage collector will reclaim the expired object only when the memory space is insufficient.

Interviewer: The initial size is 16. When will it be expanded and how will it be expanded?

Rhubarb: The current capacity will be expanded when it reaches 2/3 of the total capacity, for example, the initial size is 16, and the capacity will be expanded when the number of elements in the array reaches 12. The process of expansion can be summarized as follows: expand the original array by twice, and rehash the data in the old array into the new array. If a hash conflict occurs, continue to look for empty elements.

If the interviewer continues to ask expansion ideas, you can refer to the following figure, combined with the source code to understand.

Capacity Expansion Process

Interviewer: If it encounters a hash conflict, how does threadLocal resolve it?

Rhubarb: ThreadLocalMap resolves Hash collisions not as a linked list but as a linear probe

Linear detection of rhubarb small Class: Determine the position of elements in the table array according to the hashcode value of the initial key. If it is found that elements with other key values have been occupied in this position, the fixed algorithm is used to find the next position of a certain step length and judge successively until it finds the position that can be stored.

Note that hash conflicts are resolved in a different way than hashMap does.

Interviewer: Do you know the initialization process of threadLocal and when it will be initialized?

Rhubarb: The value is initialized when the user first calls the get() method.

Here you can take a look at the source code.

Sets the initial value of the thread-local variable for the current thread. When calling the get() method, if the user overrides the initialValue() method, it initializes it with the overridden logic. Otherwise, the set() method is automatically called to initialize the value. Normally, this method is called at most once, but if the remove() method is called after get() to remove the element, The method may be called a second time. Method returns null by default. If the user wants to return a non-null value, it needs to subclass {@code ThreadLocal} to override the method.

// Users need to implement their own initialization methods
protected T initialValue(a) {
    return null;
}
Copy the code

Interviewer: Are there any downsides to ThreadLocal?

Remember, the interviewer is probably asking about memory leaks in ThreadLocal

Rhubarb: Memory leaks occur with ThreadLocal. A key in a threadlocalMap is a weak reference to threadLocal-entry. If there is no other dependency on threadLocalmap-entry, the key is reclaimed, but the corresponding value is not. If the key is null but the value is not null, then no object is using the value and the Gc will not reclaim the object, causing a memory leak.

Interviewer: Is there any way to avoid memory leaks

Rhubarb: This is already considered in the underlying implementation. When calling the set(), get(), and remove() methods, records with null keys are cleared. It is therefore best to call the remove() method manually after using the ThreadLocal method.

A memory leak occurs only when the remove() method is not manually called after a record with a null key is present, and the get(), set(), and remove() methods are never called again.

Interviewer: You seem to know a lot about this. Is it useful in your job?

Rhubarb: The verification of user login information in our project is realized through ThreadLocal. In the initialization method of ThreadLocal, the user login information is verified on the third-party service platform, and the resolved user login information is put into the user information wrapped by ThreadLocal. This avoids frequent calls to third-party users for user information and avoids threads.

Interviewer: Well, let’s see…

Interview to be continued… .

Of course, if every question can be answered in this way, the Offer will come naturally.

conclusion

The original intention is to think that the answer is more likely to be perfect, but limited knowledge, inevitably there will be mistakes, if you find mistakes, you can add my wechat communication. (There was no comment on the official wechat account. Wechat id: X1032838190)

There will be a follow-up article on ThreadLocal source code in depth, which will share the source code of ThreadLocal.

One day

In addition, pay attention to the rhubarb running public number, the first time to harvest the exclusive arrangement of the interview actual combat record and interview knowledge summary.

I’m Rhubarb, a programmer who can only write HelloWorld, and I’ll see you next time.