Local flavor words of love: recommend a 0 card and very sweet snack, my mouth
preface
First of all, what are the application scenarios of ThreadLocal?
In general, ThreadLocal is used in a project to hold information about a user (such as session, etc.). It binds the current user to the current thread and can retrieve this information from anywhere in the same thread.
So what are the downsides of ThreadLocal?
ThreadLocal binds data to the current thread, so what? Yes, if it’s not the same thread, you can’t get data from another thread. The InheritableThreadLocal is designed to solve this problem
How does ThreadLocal store data?
-
ThreadLocal’s set method
How does the set method save data
public void set(T value) { // Get the current thread object Thread t = Thread.currentThread(); // Get the ThreadLocalMap object maintained by the current thread. ThreadLocalMap map = getMap(t); if(map ! =null) // Save directly map.set(this, value); else // Create 'ThreadLocalMap' and save it createMap(t, value); } Copy the code
Each value is stored in a ThreadLocalMap maintained by each thread and is bound to each thread, so it looks like the same ThreadLocal object is called to store data, but instead of storing data in a ThreadLocal, Instead, they are stored in a ThreadLocalMap maintained by Thread to achieve resource isolation.
-
Data cannot be shared in multiple threads
Therefore, the data stored in thread A can be retrieved arbitrarily in thread A. However, if A new thread B is opened at this time, the data stored in thread A cannot be retrieved by thread B. Since there are two different threads, when fetching data, you need to fetch the current Thread Thread object, then the ThreadLocalMap maintained by the current Thread, and then the specified data. Thread is not a single Thread, so of course you can’t get data from other threads
Just look at ThreadLocal’s get method
public T get(a) { // First get the current thread object Thread t = Thread.currentThread(); // Get the ThreadLocalMap maintained by the current thread object ThreadLocalMap map = getMap(t); if(map ! =null) { // Get the value of the current key(threadLocal object) from 'ThreadLocalMap' ThreadLocalMap.Entry e = map.getEntry(this); if(e ! =null) { T result = (T)e.value; returnresult; }}return setInitialValue(); } Copy the code
How does InheritableThreadLocal pass data?
InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal InheritableThreadLocal However, this sharing is one-time, and if the parent thread updates the value of ThreadLocal, the updated data will not be synchronized
-
Sample code for parent and child threads to share data
private static InheritableThreadLocal<Integer> inheritableThreadLocal = new InheritableThreadLocal<>(); @Test public void asyncInherriableThreadLocal(a) { // Save data to InheritableThreadLocal in the main thread inheritableThreadLocal.set(300); // Get the data in InheritableThreadLocal in child thread 1 new Thread(() -> { System.out.println("future1---inheritableThreadLocal:" + inheritableThreadLocal.get()); }).start(); TimeUnit.SECONDS.sleep(1); System.out.println("The main - inheritableThreadLocal." + inheritableThreadLocal.get()); } Copy the code
Console output:
Future1 inheritableThreadLocal: -- -300The main - inheritableThreadLocal:300 Copy the code
Data stored in the main thread is available in thread 1, meaning that the InheritableThreadLocal parent thread can share data
-
How can parent and child threads share data
-
What happens when you create a thread?
- The first step,
new Thread()
In the callinit()
private void init(ThreadGroup g, Runnable target, String name, long stackSize) { // Note that the last parameter 'true' is enabled by default init(g, target, name, stackSize, null.true); } Copy the code
- The second step is to determine whether it is enabled
dd
, and then executes the one that creates the current threadThreadLocalMap
private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) {...if(inheritThreadLocals && parent.inheritableThreadLocals ! =null) // Create the 'ThreadLocalMap' object of the current thread and use the 'inheritableThreadLocals' variable maintained by the parent thread this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); . }Copy the code
- The third step will be the parent thread
ThreadLocalMap
Copies a copy of the data in theThreadLocalMap
(This is why InheritableThreadLocal can share data)
private ThreadLocalMap(ThreadLocalMap parentMap) { // Get the Entry array of the parent thread's 'ThreadLocalMap' Entry[] parentTable = parentMap.table; int len = parentTable.length; setThreshold(len); table = new Entry[len]; // Traverses the Entry array in the parent thread's 'ThreadLocalMap' for (int j = 0; j < len; j++) { Entry e = parentTable[j]; if(e ! =null) { @SuppressWarnings("unchecked") ThreadLocal<Object> key = (ThreadLocal<Object>) e.get(); if(key ! =null) { // Get the value of the parent thread Object value = key.childValue(e.value); // Create a new Entry object to save to 'ThreadLocalMap' Entry c = new Entry(key, value); int h = key.threadLocalHashCode & (len - 1); while(table[h] ! =null) h = nextIndex(h, len); // Save to 'Entry[]' maintained by ThreadLocalMap of the current thread for data transfertable[h] = c; size++; }}}}Copy the code
- The first step,
The third step is how InheritableThreadLocal passes data from the current thread to the child thread, which is why the child thread doesn’t synchronize updates to the current thread.
-
A small summary
-
How can data be passed to child threads?
When a child thread is created in the current thread, the default ThreadLocalMap of the current thread is traversed, and all data in the current thread is copied to the ThreadLocalMap of the new thread
-
Why can’t I synchronize updates?
Because InheritableThreadLocal does not use a container to copy data to a newly created thread, it can only synchronize data at the time of creation, not update data.
Welcome to the wechat public account “code on the finger tip”
Your likes and attention are the biggest motivation for writing articles