当前位置:网站首页>Goose factory, everything about ThreadLocal
Goose factory, everything about ThreadLocal
2022-06-21 15:44:00 【JAVA Chinese community】
1. The underlying structure
ThreadLocal The bottom layer has a default capacity of 16 Array composition of ,k yes ThreadLocal References to objects ,v Is to put TheadLocal Value
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}The array is similar to HashMap, Hash conflicts are not handled with linked lists / Red black tree treatment , Instead, use the chain address method , That is, try to put the order into the next subscript position of the hash conflict subscript .
The array can also be expanded .
2. working principle
One ThreadLocal Object maintains a ThreadLocalMap Inner class object ,ThreadLocalMap Object is where the key value is stored .
More precisely , yes ThreadLocalMap Of Entry The inner class is where the key value is stored
See source code set(),createMap() You know .
Because a Thread The object maintains one ThreadLocal.ThreadLocalMap Member variables , And ThreadLocal When the set values , Acquired ThreadLocalMap It is the of the current thread object ThreadLocalMap.
// obtain ThreadLocalMap Source code
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}So each thread pair ThreadLocal Our operations do not interfere with each other , namely ThreadLocal It can realize thread isolation
3. Use
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set(" Qixi is learning Java");
Integer i = threadLocal.get()
// i = Qixi is learning Java4. Why? ThreadLocal.ThreadLocalMap The bottom layer is the length 16 What about arrays of ?
Yes ThreadLocal See page for the operation of 3 spot , You can see ThreadLocal Every time set The method is the same key( Because it's the same ThreadLocal object , therefore key It must all be the same ) To operate .
Do this , Seems right ThreadLocal Your operation will always only save 1 It's worth , The length used is 1 Isn't it fragrant ? Why use 16 What about the length ?
Okay , In fact, there is a place to pay attention to ,ThreadLocal Multiple values can be saved
How to save multiple values ? Look at the code below :
// Execute the following code in the main thread :
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set(" Qixi is learning Java");
ThreadLocal<String> threadLocal2 = new ThreadLocal<>();
threadLocal2.set(" Qixi is learning Java2");After code execution , It looks like new 了 2 individual ThreadLocal object , But actually , Data is stored in the same ThreadLocal.ThreadLocalMap Up operation
Again :ThreadLocal.ThreadLocalMap That's where data is accessed ,ThreadLocal It's just api Call entrance ). The truth is there ThreadLocal Class source code getMap()
Therefore, the final result of the above code is ThreadLocalMap Save 2 Different ThreadLocal Object as key, Corresponding value by Qixi is learning Java、 Qixi is learning Java2.
Let's take another look ThreadLocal Of set Method
public void set(T value) {
Thread t = Thread.currentThread();
// Here every time set Before , Will be called getMap(t) Method ,t Is the current call set Method thread
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
// a key : Return call set Method thread ( An example is the main thread ) Of ThreadLocal object .
// So no matter api The caller new How many? ThreadLocal object , It always returns the calling thread ( An example is the main thread ) Of ThreadLocal.ThreadLocalMap Object for the calling thread to access data .
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
// t.threadLocals The statement of
ThreadLocal.ThreadLocalMap threadLocals = null;
// There is only one way to construct
public ThreadLocal() {
}5. The data is stored in an array , Then how to solve hash The question of conflict
Use chain address method to solve .
How to solve it ? Look at the execution get、set Method time :
set:
And array key Equal to the ThreadLocal, The location element is overwritten
Or find the next empty location , Until you find an empty or key Until equal .
according to ThreadLocal Object's hash value , Locate the ThreadLocalMap Position in array .
If there is no element in the position, put it directly in the position
If there are elements
get:
according to ThreadLocal Object's hash value , Locate the ThreadLocalMap Position in array .
If it's not consistent , Just judge the next position
Otherwise, take it out directly
// Array element structure
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}6. ThreadLocal Potential memory leak
Three pre knowledge :
ThreadLocal Object maintains a ThreadLocalMap Inner class
ThreadLocalMap Object maintains another Entry Inner class , And this class inherits weak references
WeakReference<ThreadLocal<?>>, Used to store as key Of ThreadLocal object ( Visible at the bottom Entry Constructor source code ), You can see the last part of the source code .Whether the current memory space is enough or not ,GC when JVM Will reclaim the memory of weak references
because ThreadLocal As a weak reference Entry Medium Key Variable references , So if ThreadLocal There is no external strong reference to it , that ThreadLocal Next time JVM Garbage collection is recycled .
This is the time Entry Medium key Has been recovered , but value Because it's a strong reference , So it won't be recycled by the garbage collector . such ThreadLocal If your thread keeps running ,value You never get recycled , Cause a memory leak .
If you want to avoid memory leaks , have access to ThreadLocal Object's remove() Method
7. Why? ThreadLocalMap Of key Is a weak reference
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}Why is it designed like this , This is divided into two cases to discuss :
key Use strong references : Only create ThreadLocal Your thread is still running , that ThreadLocalMap The key value of will leak memory , because ThreadLocalMap Its life cycle is the same as the one that created it Thread object .
key Using weak references : It's a rescue measure , At least weakly referenced values can be used in time GC, Reduce memory leaks . in addition , Even if it's not manually deleted , As a key ThreadLocal It will also be recycled . because ThreadLocalMap call set、get、remove when , Will first judge what should be done before value Corresponding key Whether it is consistent with the currently invoked key equal . If it's not equal , Explain the previous key It's been recycled , here value It will also be recycled . therefore key Using weak references is the best solution .
8. How parent and child threads share ThreadLocal data
Main thread creation InheritableThreadLocal Object time , Would be t.inheritableThreadLocals Variable creation ThreadLocalMap, Initialize it . among t Is the current thread , The main thread
When creating a child thread , stay Thread Construction method of , Will check its parent thread inheritableThreadLocals Is it null. From 1 The next step is not to null, next Will parent thread's inheritableThreadLocals Copy this value to the sub thread .
InheritableThreadLocal Rewrote getMap, createMap, All of them are Thread.inheritableThreadLocals Variable
as follows :
public class InheritableThreadLocal<T> extends ThreadLocal<T>
The first 1 Step : Yes InheritableThreadLocal initialization
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}
The first 2 Step : When creating a child thread , Determine the of the parent thread inheritableThreadLocals Is it empty . Copy non empty
// Thread In the construction method , The following logic must be executed
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
The first 3 Step : The object of use is 1 Step created inheritableThreadLocals object
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}
}
// Example :
// result : Able to output 「 Parent thread - Qixi is learning Java」
ThreadLocal threadLocal = new InheritableThreadLocal();
threadLocal.set(" Parent thread - Qixi is learning Java");
Thread t = new Thread(() -> System.out.println(threadLocal.get()));
t.start();
// result :null, Cannot output 「 Sub thread - Qixi is learning Java」
ThreadLocal threadLocal2 = new InheritableThreadLocal();
Thread t2 = new Thread(() -> {
threadLocal2.set(" Sub thread - Qixi is learning Java");
});
t2.start();
System.out.println(threadLocal2.get());
Previous recommendation Interview shock 55:delete、drop、truncate What's the difference? ?
Face slag counter attack :MyBatis Chain link 20 ask , Who can resist this ?
Face slag counter attack :RocketMQ Twenty three questions

边栏推荐
- Brain: machine learning reveals two different neuroanatomical subtypes of schizophrenia
- Metric win computer application
- Finding minimum spanning tree by using union search set
- C language to achieve three chess (detailed explanation)
- Build an efficient and scalable result cache
- A horse stopped a pawn
- 階乘求和
- [Yugong series] February 2022 wechat applet -app Debug JSON configuration attribute
- Defcampctf2122 Forensics
- 进程之间使用共享内存通信
猜你喜欢

GO语言-type关键字

Metric win computer application

Best practice | how to use Tencent cloud micro build to develop enterprise portal applications from 0 to 1

Blazor概述和路由

鹅厂一面,有关 ThreadLocal 的一切

建立自己的网站(4)
![[go] goroutine pool](/img/0c/4e78c59f9b4f963035c911cee3d62d.jpg)
[go] goroutine pool

The application of RPC technology and its framework sekiro in crawler reverse, encrypting data is a shuttle!

2022awe opened in March, and Hisense conference tablet was shortlisted for the review of EPLAN Award

Comprehensive learning notes for intermediate network engineer in soft test (nearly 40000 words)
随机推荐
[go] time package
Talk about MySQL's locking rule "hard hitting MySQL series 15"
Jason Basics
GO语言-指针
What's wrong with the if judgment of pbootcms and the direct display of labels?
Select article (039) - when the button is clicked, event What is target?
“我这个白痴,招到了一堆只会‘谷歌’的程序员!”
In 2021, China's deposit balance continued to grow, and the balance of RMB and foreign currency deposits reached a record high [figure]
Leetcode: number of good subsets (backtracking + state compression +dfs + pruning)
Soft test intermediate network engineering test site
PLSQL learning log
2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?
Research Report on the overall scale, major producers, major regions, products and application segments of active aluminum chloride in the global market in 2022
[Yugong series] February 2022 wechat applet -app Subpackages and preloadrule of JSON configuration attribute
Go language - Interface
Native JS routing, iframe framework
AAAI 2022 | sasa: rethinking point cloud sampling in 3D object detection
Not only products, FAW Toyota can give you "all-round" peace of mind
[pytorch basic tutorial 29] DIN model
A pit trodden in the equivalence comparison of integer

